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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-07-16 14:38:23 +0300
committerJacques Lucke <jacques@blender.org>2020-07-16 14:38:23 +0300
commit2ddb3dc617a5ad3dd5882cde8c088127bd57f916 (patch)
treebd6405fd9184a5f1437dbc9493a28507e6edc9ec /source/blender
parent56aa5b0d8c6b66369f979e8bee4f1bd99454a99f (diff)
Nodes: support default function for partially implemented nodes
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_node_tree_multi_function.hh27
-rw-r--r--source/blender/blenkernel/intern/node_tree_multi_function.cc48
-rw-r--r--source/blender/functions/FN_multi_function_builder.hh11
-rw-r--r--source/blender/functions/intern/multi_function_builder.cc29
4 files changed, 98 insertions, 17 deletions
diff --git a/source/blender/blenkernel/BKE_node_tree_multi_function.hh b/source/blender/blenkernel/BKE_node_tree_multi_function.hh
index dcbd551591f..95a6c61da7f 100644
--- a/source/blender/blenkernel/BKE_node_tree_multi_function.hh
+++ b/source/blender/blenkernel/BKE_node_tree_multi_function.hh
@@ -88,6 +88,7 @@ class MFNetworkTreeMap {
void add(const DSocket &dsocket, fn::MFSocket &socket)
{
BLI_assert(dsocket.is_input() == socket.is_input());
+ BLI_assert(dsocket.is_input() || sockets_by_dsocket_id_[dsocket.id()].size() == 0);
sockets_by_dsocket_id_[dsocket.id()].append(&socket);
}
@@ -98,6 +99,8 @@ class MFNetworkTreeMap {
void add(const DOutputSocket &dsocket, fn::MFOutputSocket &socket)
{
+ /* There can be at most one matching output socket. */
+ BLI_assert(sockets_by_dsocket_id_[dsocket.id()].size() == 0);
sockets_by_dsocket_id_[dsocket.id()].append(&socket);
}
@@ -319,11 +322,11 @@ class SocketMFNetworkBuilder : public MFNetworkBuilderBase {
*/
class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
private:
- const DNode &node_;
+ const DNode &dnode_;
public:
- NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &node)
- : MFNetworkBuilderBase(common), node_(node)
+ NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &dnode)
+ : MFNetworkBuilderBase(common), dnode_(dnode)
{
}
@@ -331,12 +334,20 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
* Tells the builder to build a function that corresponds to the node that is being built. It
* will try to match up sockets.
*/
- template<typename T, typename... Args> void construct_and_set_matching_fn(Args &&... args)
+ template<typename T, typename... Args> T &construct_and_set_matching_fn(Args &&... args)
{
- const fn::MultiFunction &function = this->construct_fn<T>(std::forward<Args>(args)...);
+ T &function = this->construct_fn<T>(std::forward<Args>(args)...);
this->set_matching_fn(function);
+ return function;
}
+ const fn::MultiFunction &get_not_implemented_fn()
+ {
+ return this->get_default_fn("Not Implemented (" + dnode_.name() + ")");
+ }
+
+ const fn::MultiFunction &get_default_fn(StringRef name);
+
/**
* Tells the builder that the given function corresponds to the node that is being built. It will
* try to match up sockets. For that it skips unavailable and non-data sockets.
@@ -344,7 +355,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
void set_matching_fn(const fn::MultiFunction &function)
{
fn::MFFunctionNode &node = common_.network.add_function(function);
- common_.network_map.add_try_match(node_, node);
+ common_.network_map.add_try_match(dnode_, node);
}
/**
@@ -352,7 +363,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
*/
bNode &bnode()
{
- return *node_.node_ref().bnode();
+ return *dnode_.node_ref().bnode();
}
/**
@@ -360,7 +371,7 @@ class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
*/
const DNode &dnode() const
{
- return node_;
+ return dnode_;
}
};
diff --git a/source/blender/blenkernel/intern/node_tree_multi_function.cc b/source/blender/blenkernel/intern/node_tree_multi_function.cc
index 4e505db9b9d..942f8e9a87a 100644
--- a/source/blender/blenkernel/intern/node_tree_multi_function.cc
+++ b/source/blender/blenkernel/intern/node_tree_multi_function.cc
@@ -31,6 +31,35 @@ static std::optional<fn::MFDataType> try_get_multi_function_data_type_of_socket(
return bsocket->typeinfo->get_mf_data_type();
}
+const fn::MultiFunction &NodeMFNetworkBuilder::get_default_fn(StringRef name)
+{
+ Vector<fn::MFDataType, 10> input_types;
+ Vector<fn::MFDataType, 10> output_types;
+
+ for (const DInputSocket *dsocket : dnode_.inputs()) {
+ if (dsocket->is_available()) {
+ std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+ dsocket->bsocket());
+ if (data_type.has_value()) {
+ input_types.append(*data_type);
+ }
+ }
+ }
+ for (const DOutputSocket *dsocket : dnode_.outputs()) {
+ if (dsocket->is_available()) {
+ std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+ dsocket->bsocket());
+ if (data_type.has_value()) {
+ output_types.append(*data_type);
+ }
+ }
+ }
+
+ const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_DefaultOutput>(
+ name, input_types, output_types);
+ return fn;
+}
+
static void insert_dummy_node(CommonMFNetworkBuilderData &common, const DNode &dnode)
{
constexpr uint stack_capacity = 10;
@@ -138,20 +167,21 @@ static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
}
if (from_dsockets.size() == 1) {
- if (is_multi_function_data_socket(from_dsockets[0]->bsocket())) {
- return &common.network_map.lookup(*from_dsockets[0]);
- }
- else {
+ const DOutputSocket &from_dsocket = *from_dsockets[0];
+ if (!from_dsocket.is_available()) {
return nullptr;
}
+ if (is_multi_function_data_socket(from_dsocket.bsocket())) {
+ return &common.network_map.lookup(from_dsocket);
+ }
+ return nullptr;
}
else {
- if (is_multi_function_data_socket(from_group_inputs[0]->bsocket())) {
- return &common.network_map.lookup(*from_group_inputs[0]);
- }
- else {
- return nullptr;
+ const DGroupInput &from_group_input = *from_group_inputs[0];
+ if (is_multi_function_data_socket(from_group_input.bsocket())) {
+ return &common.network_map.lookup(from_group_input);
}
+ return nullptr;
}
}
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index 6e7efb21850..c2c95f7c355 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -302,6 +302,17 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
}
};
+class CustomMF_DefaultOutput : public MultiFunction {
+ private:
+ uint output_amount_;
+
+ public:
+ CustomMF_DefaultOutput(StringRef name,
+ Span<MFDataType> input_types,
+ Span<MFDataType> output_types);
+ void call(IndexMask mask, MFParams params, MFContext context) const override;
+};
+
} // namespace blender::fn
#endif /* __FN_MULTI_FUNCTION_BUILDER_HH__ */
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 889a2595aab..7797c19d563 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -87,4 +87,33 @@ void CustomMF_GenericConstantArray::call(IndexMask mask,
}
}
+CustomMF_DefaultOutput::CustomMF_DefaultOutput(StringRef name,
+ Span<MFDataType> input_types,
+ Span<MFDataType> output_types)
+ : output_amount_(output_types.size())
+{
+ MFSignatureBuilder signature = this->get_builder(name);
+ for (MFDataType data_type : input_types) {
+ signature.input("Input", data_type);
+ }
+ for (MFDataType data_type : output_types) {
+ signature.output("Output", data_type);
+ }
+}
+void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const
+{
+ for (uint param_index : this->param_indices()) {
+ MFParamType param_type = this->param_type(param_index);
+ if (!param_type.is_output()) {
+ continue;
+ }
+
+ if (param_type.data_type().is_single()) {
+ GMutableSpan span = params.uninitialized_single_output(param_index);
+ const CPPType &type = span.type();
+ type.fill_uninitialized_indices(type.default_value(), span.buffer(), mask);
+ }
+ }
+}
+
} // namespace blender::fn