46using bke::bNodeTreeZone;
47using bke::bNodeTreeZones;
53 this->
value.destruct();
59 if (
string.
size() <= 100) {
71 const std::shared_ptr<const fn::FieldInputs> &field_input_nodes = field.
node().field_inputs();
75 if (field_input_nodes) {
76 field_inputs.
extend(field_input_nodes->deduplicated_nodes.begin(),
77 field_input_nodes->deduplicated_nodes.end());
82 const int index_a = int(a.category());
83 const int index_b = int(b.category());
84 if (index_a == index_b) {
85 return a.socket_inspection_name().size() < b.socket_inspection_name().size();
87 return index_a < index_b;
90 for (
const FieldInput &field_input : field_inputs) {
91 this->input_tooltips.append(field_input.socket_inspection_name());
124 switch (component->type()) {
165 if (
const bke::GizmoEditHints *gizmo_edit_hints = edit_component.gizmo_edit_hints_.get()) {
172 if (
const Volume *volume = volume_component.get()) {
181 if (
const GreasePencil *grease_pencil = grease_pencil_component.get()) {
183 info.
layers_num = grease_pencil->layers().size();
187 if (unique_layer_names.
add(layer_name)) {
199struct GridIsEmptyOp {
200 const openvdb::GridBase &base_grid;
205 result =
static_cast<const GridType &
>(base_grid).empty();
215 bke::VolumeTreeAccessToken token;
216 const openvdb::GridBase &vdb_grid = grid->grid(token);
219 GridIsEmptyOp is_empty_op{vdb_grid};
220 if (BKE_volume_grid_type_operation(grid_type, is_empty_op)) {
236 const std::optional<ClosureSourceLocation> &source_location,
237 std::shared_ptr<ClosureEvalLog>
eval_log)
240 if (source_location) {
241 const bNodeTree *tree_eval = source_location->tree;
245 source_location->closure_output_node_id,
246 source_location->compute_context_hash};
252 switch (report.
type) {
274 : root_log_(root_log), tree_loggers_(std::move(tree_loggers))
278 children_hashes_.add(
hash);
293 {node.
identifier, socket.index(), std::move(value_log)});
296 auto log_generic_value = [&](
const CPPType &type,
const void *value) {
297 void *buffer = this->
allocator->allocate(type);
314 const bke::GVolumeGrid grid = value_variant.
extract<bke::GVolumeGrid>();
322 items.
append({item.key, item.type});
330 std::optional<ClosureSourceLocation> source_location;
331 std::shared_ptr<ClosureEvalLog> eval_log;
340 source_location = closure->source_location();
341 eval_log = closure->eval_log_ptr();
344 std::move(
inputs), std::move(
outputs), source_location, eval_log));
347 value_variant.convert_to_single();
349 if (value.
type()->
is<std::string>()) {
350 const std::string &
string = *value.
get<std::string>();
354 log_generic_value(*value.
type(), value.
get());
359 log_generic_value(type, value.
get());
367 log->geometry.ensure_owns_direct_data();
374 switch (propagation) {
390 if (reduced_node_warnings_) {
394 reduced_node_warnings_ =
true;
402 if (ID *id = *cb_data->id_pointer) {
403 if (GS(id->name) == ID_NT) {
404 const bNodeTree *tree = reinterpret_cast<const bNodeTree *>(id);
405 map.add(id->session_uid, tree);
412 this->ensure_node_warnings(map);
417 if (reduced_node_warnings_) {
431 if (reduced_node_warnings_) {
434 if (tree_loggers_.is_empty()) {
437 const std::optional<uint32_t> tree_uid = tree_loggers_[0]->tree_orig_session_uid;
456 GeoTreeLog &child_log = root_log_->get_tree_log(child_hash);
457 if (child_log.tree_loggers_.is_empty()) {
460 const GeoTreeLogger &first_child_logger = *child_log.tree_loggers_[0];
462 const std::optional<int32_t> &caller_node_id = first_child_logger.
parent_node_id;
463 if (
tree && caller_node_id) {
464 if (
const bNode *caller_node =
tree->node_by_id(*caller_node_id)) {
469 if (caller_node_id.has_value()) {
470 this->
nodes.lookup_or_add_default(*caller_node_id)
480 reduced_node_warnings_ =
true;
485 if (reduced_execution_times_) {
490 const std::chrono::nanoseconds duration = timings.
end - timings.
start;
491 this->
nodes.lookup_or_add_default_as(timings.
node_id).execution_time += duration;
495 reduced_execution_times_ =
true;
500 if (reduced_socket_values_) {
513 reduced_socket_values_ =
true;
518 if (reduced_viewer_node_logs_) {
526 reduced_viewer_node_logs_ =
true;
531 if (reduced_existing_attributes_) {
536 auto handle_value_log = [&](
const ValueLog &value_log) {
547 for (
const ValueLog *value_log : node_log.input_values_.values()) {
548 handle_value_log(*value_log);
550 for (
const ValueLog *value_log : node_log.output_values_.values()) {
551 handle_value_log(*value_log);
554 reduced_existing_attributes_ =
true;
559 if (reduced_used_named_attributes_) {
563 auto add_attribute = [&](
const int32_t node_id,
566 this->
nodes.lookup_or_add_default(node_id).used_named_attributes.lookup_or_add(attribute_name,
577 GeoTreeLog &child_log = root_log_->get_tree_log(child_hash);
578 if (child_log.tree_loggers_.is_empty()) {
582 if (
const std::optional<int32_t> &parent_node_id = child_log.tree_loggers_[0]->parent_node_id)
585 add_attribute(*parent_node_id, item.key, item.value);
589 reduced_used_named_attributes_ =
true;
594 if (reduced_debug_messages_) {
600 .debug_messages.append(debug_message.
message);
603 reduced_debug_messages_ =
true;
608 if (reduced_evaluated_gizmo_nodes_) {
613 tree_logger->evaluated_gizmo_nodes)
619 reduced_evaluated_gizmo_nodes_ =
true;
624 if (reduced_layer_names_) {
630 auto handle_value_log = [&](
const ValueLog &value_log) {
632 if (
geo_log ==
nullptr || !
geo_log->grease_pencil_info.has_value()) {
635 for (
const std::string &name :
geo_log->grease_pencil_info->layer_names) {
641 for (
const ValueLog *value_log : node_log.input_values_.values()) {
642 handle_value_log(*value_log);
644 for (
const ValueLog *value_log : node_log.output_values_.values()) {
645 handle_value_log(*value_log);
649 reduced_layer_names_ =
true;
661 if (query_socket.is_multi_input()) {
668 sockets_to_check.
push(&query_socket);
669 added_sockets.
add(&query_socket);
671 while (!sockets_to_check.
is_empty()) {
673 const bNode &node = socket.owner_node();
675 ValueLog *value_log = socket.is_input() ?
676 node_log->input_values_.lookup_default(socket.index(),
nullptr) :
677 node_log->output_values_.lookup_default(socket.index(),
nullptr);
678 if (value_log !=
nullptr) {
683 if (socket.is_input()) {
687 if (added_sockets.
add(&from_socket)) {
688 sockets_to_check.
push(&from_socket);
693 if (node.is_reroute()) {
694 const bNodeSocket &input_socket = node.input_socket(0);
695 if (added_sockets.
add(&input_socket)) {
696 sockets_to_check.
push(&input_socket);
701 if (added_sockets.
add(&from_socket)) {
702 sockets_to_check.
push(&from_socket);
706 else if (node.is_muted()) {
707 if (
const bNodeSocket *input_socket = socket.internal_link_input()) {
708 if (added_sockets.
add(input_socket)) {
709 sockets_to_check.
push(input_socket);
714 if (added_sockets.
add(&from_socket)) {
715 sockets_to_check.
push(&from_socket);
730 const void *src_value = value_log.
value.
get();
736 if (!conversions.
is_convertible(src_type, dst_type) && src_type != dst_type) {
750 return id->session_uid;
753 return id_orig->session_uid;
760 LocalData &local_data = data_per_thread_.local();
762 local_data.tree_logger_by_context;
764 compute_context.
hash());
765 if (tree_logger_ptr) {
766 return *tree_logger_ptr;
770 tree_logger.allocator = &local_data.allocator;
772 std::optional<uint32_t> parent_tree_session_uid;
773 if (parent_compute_context !=
nullptr) {
774 tree_logger.parent_hash = parent_compute_context->
hash();
780 tree_logger.parent_node_id.emplace(context->node_id());
781 if (
const bNode *caller_node = context->node()) {
788 tree_logger.parent_node_id.emplace(context->output_node_id());
789 tree_logger.tree_orig_session_uid = parent_tree_session_uid;
791 else if (
const auto *context =
795 tree_logger.parent_node_id.emplace(context->output_node_id());
796 tree_logger.tree_orig_session_uid = parent_tree_session_uid;
801 tree_logger.parent_node_id.emplace(context->output_node_id());
802 tree_logger.tree_orig_session_uid = parent_tree_session_uid;
807 tree_logger.parent_node_id.emplace(context->node_id());
808 const std::optional<nodes::ClosureSourceLocation> &location =
809 context->closure_source_location();
810 if (location.has_value()) {
820 reinterpret_cast<const ID *
>(nmd->node_group));
827 tree_logger.tree_orig_session_uid =
tree->id.session_uid;
835 GeoTreeLog &reduced_tree_log = *tree_logs_.lookup_or_add_cb(compute_context_hash, [&]() {
837 for (LocalData &local_data : data_per_thread_) {
839 compute_context_hash);
840 if (tree_log !=
nullptr) {
841 tree_logs.
append(tree_log->get());
844 return std::make_unique<GeoTreeLog>(
this, std::move(tree_logs));
846 return reduced_tree_log;
870 snode, compute_context_cache);
876 if (tree_zones ==
nullptr) {
891 std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
893 if (!object_and_modifier) {
896 return object_and_modifier->nmd->runtime->eval_log.get();
904 return log.log.get();
920 for (
const auto item : hash_by_zone.
items()) {
922 tree_logs_by_zone.
add(item.key, &tree_log);
924 return {tree_logs_by_zone};
929 const std::optional<ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
931 if (!parsed_path.has_value()) {
934 const Object *
object = parsed_path->object;
937 if (md->persistent_uid == parsed_path->modifier_uid) {
943 if (nmd ==
nullptr) {
955 *elem, compute_context_cache, compute_context);
956 if (!compute_context) {
965 parsed_path->viewer_node_id,
nullptr);
971 : tree_logs_by_zone_(std::move(tree_logs_by_zone))
977 return tree_logs_by_zone_.lookup_default(zone,
nullptr);
1004 for (
GeoTreeLog *tree_log : tree_logs_by_zone_.values()) {
1006 callback(*tree_log);
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
#define FOREACH_NODETREE_END
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
int BKE_volume_num_grids(const Volume *volume)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
const char * BLI_str_find_prev_char_utf8(const char *p, const char *str_start) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1
bool DEG_is_original(const T *id)
bool DEG_is_evaluated(const T *id)
ID * DEG_get_original_id(ID *id)
T * DEG_get_original(T *id)
@ NODE_WARNING_PROPAGATION_NONE
@ NODE_WARNING_PROPAGATION_ONLY_ERRORS_AND_WARNINGS
@ NODE_WARNING_PROPAGATION_ONLY_ERRORS
@ NODE_WARNING_PROPAGATION_ALL
SpaceNodeGeometryNodesType
@ SNODE_GEOMETRY_MODIFIER
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
GeometryInfoLog(const bke::GeometrySet &geometry_set)
void append(const T &value)
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
const ComputeContext * parent() const
const ComputeContextHash & hash() const
const CPPType * type() const
const CPPType * type() const
destruct_ptr< T > construct(Args &&...args)
StringRefNull copy_string(StringRef str)
Value & lookup_or_add_default(const Key &key)
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
void add_new(const Key &key, const Value &value)
ItemIterator items() const &
void push(const T &value)
void append(const T &value)
void extend(Span< T > array)
const ModifierComputeContext & for_modifier(const ComputeContext *parent, const NodesModifierData &nmd)
void convert_to_uninitialized(const CPPType &from_type, const CPPType &to_type, const void *from_value, void *to_value) const
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
bool is_context_dependent_field() const
bool valid_for_socket(eNodeSocketDatatype socket_type) const
bool is_volume_grid() const
GPointer get_single_ptr() const
Vector< bNodeTreeZone * > child_zones
Vector< bNodeTreeZone * > root_zones
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
const bNodeTreeZone * get_zone_by_socket(const bNodeSocket &socket) const
const FieldNode & node() const
BundleValueLog(Vector< Item > items)
std::optional< Source > source
ClosureValueLog(Vector< Item > inputs, Vector< Item > outputs, const std::optional< ClosureSourceLocation > &source_location, std::shared_ptr< ClosureEvalLog > eval_log)
std::shared_ptr< ClosureEvalLog > eval_log
GeoTreeLog * get_main_tree_log(const bke::bNodeTreeZone *zone) const
ContextualGeoTreeLogs(Map< const bke::bNodeTreeZone *, GeoTreeLog * > tree_logs_by_zone={})
void foreach_tree_log(FunctionRef< void(GeoTreeLog &)> callback) const
FieldInfoLog(const GField &field)
~GenericValueLog() override
static ContextualGeoTreeLogs get_contextual_tree_logs(const SpaceNode &snode)
static Map< const bke::bNodeTreeZone *, ComputeContextHash > get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, bke::ComputeContextCache &compute_context_cache)
static const ViewerNodeLog * find_viewer_node_log_for_path(const ViewerPath &viewer_path)
GeoTreeLogger & get_local_tree_logger(const ComputeContext &compute_context)
GeoTreeLog & get_tree_log(const ComputeContextHash &compute_context_hash)
Vector< const GeometryAttributeInfo * > existing_attributes
void ensure_evaluated_gizmo_nodes()
void ensure_node_warnings(const NodesModifierData &nmd)
void ensure_used_named_attributes()
VectorSet< NodeWarning > all_warnings
Set< int > evaluated_gizmo_nodes
void ensure_existing_attributes()
void ensure_socket_values()
bool try_convert_primitive_socket_value(const GenericValueLog &value_log, const CPPType &dst_type, void *dst)
std::chrono::nanoseconds execution_time
void ensure_execution_times()
void ensure_viewer_node_logs()
Map< int32_t, ViewerNodeLog *, 0 > viewer_node_logs
Vector< std::string > all_layer_names
Map< StringRefNull, NamedAttributeUsage > used_named_attributes
Map< int32_t, GeoNodeLog > nodes
void ensure_layer_names()
void ensure_debug_messages()
GeoTreeLog(GeoNodesLog *root_log, Vector< GeoTreeLogger * > tree_loggers)
ValueLog * find_socket_value_log(const bNodeSocket &query_socket)
linear_allocator::ChunkedList< ViewerNodeLogWithNode > viewer_node_logs
std::optional< int32_t > parent_node_id
void log_viewer_node(const bNode &viewer_node, bke::GeometrySet geometry)
LinearAllocator * allocator
linear_allocator::ChunkedList< SocketValueLog, 16 > input_socket_values
void log_value(const bNode &node, const bNodeSocket &socket, GPointer value)
std::optional< uint32_t > tree_orig_session_uid
linear_allocator::ChunkedList< SocketValueLog, 16 > output_socket_values
Vector< ComputeContextHash > children_hashes
std::optional< EditDataInfo > edit_data_info
std::optional< GridInfo > grid_info
std::optional< MeshInfo > mesh_info
std::optional< GreasePencilInfo > grease_pencil_info
std::optional< PointCloudInfo > pointcloud_info
Vector< bke::GeometryComponent::Type > component_types
std::optional< InstancesInfo > instances_info
std::optional< VolumeInfo > volume_info
Vector< GeometryAttributeInfo > attributes
std::optional< CurveInfo > curve_info
VolumeGridType get_type(const VolumeGridData &grid)
bool attribute_name_is_anonymous(const StringRef name)
const DataTypeConversions & get_implicit_type_conversions()
const GeoOperatorLog & node_group_operator_static_eval_log()
const ComputeContext * compute_context_for_edittree(const SpaceNode &snode, bke::ComputeContextCache &compute_context_cache)
const ComputeContext * compute_context_for_zone(const bke::bNodeTreeZone &zone, bke::ComputeContextCache &compute_context_cache, const ComputeContext *parent_compute_context)
std::optional< ObjectAndModifier > get_modifier_for_node_editor(const SpaceNode &snode)
std::optional< ViewerPathForGeometryNodesViewer > parse_geometry_nodes_viewer(const ViewerPath &viewer_path)
const ComputeContext * compute_context_for_viewer_path_elem(const ViewerPathElem &elem, bke::ComputeContextCache &compute_context_cache, const ComputeContext *parent_compute_context)
static void find_tree_zone_hash_recursive(const bNodeTreeZone &zone, bke::ComputeContextCache &compute_context_cache, const ComputeContext *current, Map< const bNodeTreeZone *, ComputeContextHash > &r_hash_by_zone)
static std::optional< uint32_t > get_original_session_uid(const ID *id)
static GeoNodesLog * get_root_log(const SpaceNode &snode)
static bool warning_is_propagated(const NodeWarningPropagation propagation, const NodeWarningType warning_type)
ImplicitSharingPtr< Bundle > BundlePtr
ImplicitSharingPtr< Closure > ClosurePtr
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
static blender::bke::bNodeSocketTemplate outputs[]
static blender::bke::bNodeSocketTemplate inputs[]
struct bNodeTree * node_group
NodesModifierRuntimeHandle * runtime
struct bNodeTree * edittree
struct bNodeTree * geometry_nodes_tool_tree
Vector< const GeometryComponent * > get_components() const
void attribute_foreach(Span< GeometryComponent::Type > component_types, bool include_instances, AttributeForeachCallback callback) const
const bke::bNodeSocketType * type
NamedAttributeUsage usage
StringRefNull attribute_name
destruct_ptr< ValueLog > value
destruct_ptr< ViewerNodeLog > viewer_log
bool has_deformed_positions
Vector< std::string > layer_names
NodeWarning(NodeWarningType type, StringRef message)
StringLog(StringRef string, LinearAllocator<> &allocator)