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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc6
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc37
5 files changed, 62 insertions, 3 deletions
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 18de52ed6d4..d5fd3ff0abb 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -21,6 +21,7 @@
#include "BKE_attribute_access.hh"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
+#include "BKE_node_ui_storage.hh"
#include "BKE_persistent_data_handle.hh"
#include "DNA_node_types.h"
@@ -28,6 +29,7 @@
#include "NOD_derived_node_tree.hh"
struct Depsgraph;
+struct ModifierData;
namespace blender::nodes {
@@ -62,6 +64,7 @@ class GeoNodeExecParams {
GValueMap<StringRef> &output_values_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
+ const ModifierData *modifier_;
Depsgraph *depsgraph_;
public:
@@ -70,12 +73,14 @@ class GeoNodeExecParams {
GValueMap<StringRef> &output_values,
const PersistentDataHandleMap &handle_map,
const Object *self_object,
+ const ModifierData *modifier,
Depsgraph *depsgraph)
: node_(node),
input_values_(input_values),
output_values_(output_values),
handle_map_(handle_map),
self_object_(self_object),
+ modifier_(modifier),
depsgraph_(depsgraph)
{
}
@@ -199,8 +204,17 @@ class GeoNodeExecParams {
}
/**
+ * Add an error message displayed at the top of the node when displaying the node tree,
+ * and potentially elsewhere in Blender.
+ */
+ void error_message_add(const NodeWarningType type, std::string message) const;
+
+ /**
* Creates a read-only attribute based on node inputs. The method automatically detects which
- * input with the given name is available.
+ * input socket with the given name is available.
+ *
+ * \note This will add an error message if the string socket is active and
+ * the input attribute does not exist.
*/
ReadAttributePtr get_input_attribute(const StringRef name,
const GeometryComponent &component,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
index 8a098c366a0..d7b85953a44 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
@@ -214,6 +214,8 @@ static void randomize_attribute_on_component(GeometryComponent &component,
* doesn't already exist, don't do the operation. */
if (operation != GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE) {
if (!component.attribute_exists(attribute_name)) {
+ params.error_message_add(NodeWarningType::Error,
+ "No attribute with name '" + attribute_name + "'.");
return;
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
index 581c356742b..40187490c23 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -426,6 +426,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
static_cast<GeometryNodePointDistributeMethod>(params.node().custom1);
if (!geometry_set.has_mesh()) {
+ params.error_message_add(NodeWarningType::Error, "Geometry must contain a mesh.");
params.set_output("Geometry", std::move(geometry_set_out));
return;
}
@@ -441,7 +442,8 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>();
const Mesh *mesh_in = mesh_component.get_for_read();
- if (mesh_in == nullptr || mesh_in->mpoly == nullptr) {
+ if (mesh_in->mpoly == nullptr) {
+ params.error_message_add(NodeWarningType::Error, "Mesh has no faces.");
params.set_output("Geometry", std::move(geometry_set_out));
return;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index 11921acdb68..669b5ee4614 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -101,6 +101,12 @@ static void get_instanced_data__collection(
return;
}
+ if (BLI_listbase_is_empty(&collection->children) &&
+ BLI_listbase_is_empty(&collection->gobject)) {
+ params.error_message_add(NodeWarningType::Info, "Collection is empty.");
+ return;
+ }
+
const bool use_whole_collection = (node_storage->flag &
GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION) != 0;
if (use_whole_collection) {
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 7f4f75c294f..ebbb6f60b78 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -14,6 +14,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "DNA_modifier_types.h"
+
+#include "BKE_node_ui_storage.hh"
+
+#include "DEG_depsgraph_query.h"
+
#include "NOD_derived_node_tree.hh"
#include "NOD_geometry_exec.hh"
#include "NOD_type_callbacks.hh"
@@ -22,6 +28,23 @@
namespace blender::nodes {
+void GeoNodeExecParams::error_message_add(const NodeWarningType type, std::string message) const
+{
+ bNodeTree *btree_cow = node_.node_ref().tree().btree();
+ BLI_assert(btree_cow != nullptr);
+ if (btree_cow == nullptr) {
+ return;
+ }
+ bNodeTree *btree_original = (bNodeTree *)DEG_get_original_id((ID *)btree_cow);
+
+ BKE_nodetree_ui_storage_ensure(*btree_original);
+
+ const NodeTreeEvaluationContext context(*self_object_, *modifier_);
+
+ BKE_nodetree_error_message_add(
+ *btree_original, context, *node_.bnode(), type, std::move(message));
+}
+
const bNodeSocket *GeoNodeExecParams::find_available_socket(const StringRef name) const
{
for (const DSocket *socket : node_.inputs()) {
@@ -47,7 +70,19 @@ ReadAttributePtr GeoNodeExecParams::get_input_attribute(const StringRef name,
if (found_socket->type == SOCK_STRING) {
const std::string name = this->get_input<std::string>(found_socket->identifier);
- return component.attribute_get_for_read(name, domain, type, default_value);
+ /* Try getting the attribute without the default value. */
+ ReadAttributePtr attribute = component.attribute_try_get_for_read(name, domain, type);
+ if (attribute) {
+ return attribute;
+ }
+
+ /* If the attribute doesn't exist, use the default value and output an error message
+ * (except when the field is empty, to avoid spamming error messages). */
+ if (!name.empty()) {
+ this->error_message_add(NodeWarningType::Error,
+ std::string("No attribute with name '") + name + "'.");
+ }
+ return component.attribute_get_constant_for_read(domain, type, default_value);
}
if (found_socket->type == SOCK_FLOAT) {
const float value = this->get_input<float>(found_socket->identifier);