31using bke::bNodeTreeZone;
32using bke::bNodeTreeZones;
38 this->
value.destruct();
43 const std::shared_ptr<const fn::FieldInputs> &field_input_nodes = field.
node().field_inputs();
47 if (field_input_nodes) {
48 field_inputs.
extend(field_input_nodes->deduplicated_nodes.begin(),
49 field_input_nodes->deduplicated_nodes.end());
54 const int index_a = int(a.category());
55 const int index_b = int(b.category());
56 if (index_a == index_b) {
57 return a.socket_inspection_name().size() < b.socket_inspection_name().size();
59 return index_a < index_b;
62 for (
const FieldInput &field_input : field_inputs) {
63 this->input_tooltips.append(field_input.socket_inspection_name());
96 switch (component->type()) {
137 if (
const bke::GizmoEditHints *gizmo_edit_hints = edit_component.gizmo_edit_hints_.get()) {
144 if (
const Volume *volume = volume_component.get()) {
153 if (
const GreasePencil *grease_pencil = grease_pencil_component.get()) {
155 info.
layers_num = grease_pencil->layers().size();
164struct GridIsEmptyOp {
165 const openvdb::GridBase &base_grid;
170 result =
static_cast<const GridType &
>(base_grid).empty();
180 bke::VolumeTreeAccessToken token;
181 const openvdb::GridBase &vdb_grid = grid->grid(token);
184 GridIsEmptyOp is_empty_op{vdb_grid};
185 if (BKE_volume_grid_type_operation(grid_type, is_empty_op)) {
208 : modifier_log_(modifier_log), tree_loggers_(std::move(tree_loggers))
212 children_hashes_.add(
hash);
227 {node.
identifier, socket.index(), std::move(value_log)});
230 auto log_generic_value = [&](
const CPPType &type,
const void *value) {
248 const bke::GVolumeGrid grid = value_variant.
extract<bke::GVolumeGrid>();
255 log_generic_value(*value.
type(), value.
get());
259 log_generic_value(type, value.
get());
267 log->geometry.ensure_owns_direct_data();
274 switch (propagation) {
290 if (reduced_node_warnings_) {
309 GeoTreeLog &child_log = modifier_log_->get_tree_log(child_hash);
310 if (child_log.tree_loggers_.is_empty()) {
315 const std::optional<int32_t> &parent_node_id = child_log.tree_loggers_[0]->parent_node_id;
316 if (
tree && parent_node_id) {
317 if (
const bNode *node =
tree->node_by_id(*parent_node_id)) {
319 if (node->is_group() && node->id) {
320 child_tree =
reinterpret_cast<const bNodeTree *
>(node->id);
328 if (parent_node_id.has_value()) {
329 this->
nodes.lookup_or_add_default(*parent_node_id)
339 reduced_node_warnings_ =
true;
344 if (reduced_execution_times_) {
349 const std::chrono::nanoseconds duration = timings.
end - timings.
start;
350 this->
nodes.lookup_or_add_default_as(timings.
node_id).execution_time += duration;
354 reduced_execution_times_ =
true;
359 if (reduced_socket_values_) {
372 reduced_socket_values_ =
true;
377 if (reduced_viewer_node_logs_) {
385 reduced_viewer_node_logs_ =
true;
390 if (reduced_existing_attributes_) {
395 auto handle_value_log = [&](
const ValueLog &value_log) {
406 for (
const ValueLog *value_log : node_log.input_values_.values()) {
407 handle_value_log(*value_log);
409 for (
const ValueLog *value_log : node_log.output_values_.values()) {
410 handle_value_log(*value_log);
413 reduced_existing_attributes_ =
true;
418 if (reduced_used_named_attributes_) {
422 auto add_attribute = [&](
const int32_t node_id,
425 this->
nodes.lookup_or_add_default(node_id).used_named_attributes.lookup_or_add(attribute_name,
436 GeoTreeLog &child_log = modifier_log_->get_tree_log(child_hash);
437 if (child_log.tree_loggers_.is_empty()) {
441 if (
const std::optional<int32_t> &parent_node_id = child_log.tree_loggers_[0]->parent_node_id)
444 add_attribute(*parent_node_id, item.key, item.value);
448 reduced_used_named_attributes_ =
true;
453 if (reduced_debug_messages_) {
459 .debug_messages.append(debug_message.
message);
462 reduced_debug_messages_ =
true;
467 if (reduced_evaluated_gizmo_nodes_) {
472 tree_logger->evaluated_gizmo_nodes)
488 if (query_socket.is_multi_input()) {
495 sockets_to_check.
push(&query_socket);
496 added_sockets.
add(&query_socket);
498 while (!sockets_to_check.
is_empty()) {
500 const bNode &node = socket.owner_node();
502 ValueLog *value_log = socket.is_input() ?
503 node_log->input_values_.lookup_default(socket.index(),
nullptr) :
504 node_log->output_values_.lookup_default(socket.index(),
nullptr);
505 if (value_log !=
nullptr) {
510 if (socket.is_input()) {
514 if (added_sockets.
add(&from_socket)) {
515 sockets_to_check.
push(&from_socket);
520 if (node.is_reroute()) {
521 const bNodeSocket &input_socket = node.input_socket(0);
522 if (added_sockets.
add(&input_socket)) {
523 sockets_to_check.
push(&input_socket);
528 if (added_sockets.
add(&from_socket)) {
529 sockets_to_check.
push(&from_socket);
533 else if (node.is_muted()) {
534 if (
const bNodeSocket *input_socket = socket.internal_link_input()) {
535 if (added_sockets.
add(input_socket)) {
536 sockets_to_check.
push(input_socket);
541 if (added_sockets.
add(&from_socket)) {
542 sockets_to_check.
push(&from_socket);
557 const void *src_value = value_log.
value.
get();
563 if (!conversions.
is_convertible(src_type, dst_type) && src_type != dst_type) {
573 LocalData &local_data = data_per_thread_.local();
575 local_data.tree_logger_by_context;
577 compute_context.
hash());
578 if (tree_logger_ptr) {
579 return *tree_logger_ptr;
583 tree_logger.allocator = &local_data.allocator;
585 if (parent_compute_context !=
nullptr) {
586 tree_logger.parent_hash = parent_compute_context->
hash();
593 tree_logger.parent_node_id.emplace(typed_compute_context->node_id());
598 tree_logger.parent_node_id.emplace(typed_compute_context->output_node_id());
604 tree_logger.parent_node_id.emplace(typed_compute_context->output_node_id());
609 tree_logger.parent_node_id.emplace(typed_compute_context->output_node_id());
616 GeoTreeLog &reduced_tree_log = *tree_logs_.lookup_or_add_cb(compute_context_hash, [&]() {
618 for (LocalData &local_data : data_per_thread_) {
620 compute_context_hash);
621 if (tree_log !=
nullptr) {
622 tree_logs.
append(tree_log->get());
625 return std::make_unique<GeoTreeLog>(
this, std::move(tree_logs));
627 return reduced_tree_log;
644 storage.inspection_index);
655 r_hash_by_zone.
add_new(&zone, compute_context_builder.
hash());
659 compute_context_builder.
pop();
671 if (tree_zones ==
nullptr) {
675 hash_by_zone.
add_new(
nullptr, compute_context_builder.
hash());
695 std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
697 if (!object_and_modifier) {
700 GeoModifierLog *modifier_log = object_and_modifier->nmd->runtime->eval_log.get();
701 if (modifier_log ==
nullptr) {
706 snode, object_and_modifier->nmd->modifier.name);
708 for (
const auto item : hash_by_zone.
items()) {
710 log_by_zone.
add(item.key, &tree_log);
725 for (
const auto item : hash_by_zone.items()) {
727 log_by_zone.
add(item.key, &tree_log);
738 const std::optional<ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
740 if (!parsed_path.has_value()) {
743 const Object *
object = parsed_path->object;
746 if (md->name == parsed_path->modifier_name) {
752 if (nmd ==
nullptr) {
773 parsed_path->viewer_node_id,
nullptr);
Low-level operations for curves.
#define GEO_NODE_FOREACH_GEOMETRY_ELEMENT_OUTPUT
#define GEO_NODE_SIMULATION_OUTPUT
#define GEO_NODE_REPEAT_OUTPUT
int BKE_volume_num_grids(const Volume *volume)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
@ NODE_WARNING_PROPAGATION_NONE
@ NODE_WARNING_PROPAGATION_ONLY_ERRORS_AND_WARNINGS
@ NODE_WARNING_PROPAGATION_ONLY_ERRORS
@ NODE_WARNING_PROPAGATION_ALL
SpaceNodeGeometryNodesType
@ SNODE_GEOMETRY_MODIFIER
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
int64_t alignment() const
const ComputeContextHash hash() const
void push(Args &&...args)
const ComputeContext * parent() const
const ComputeContextHash & hash() const
const CPPType * type() const
const CPPType * type() const
destruct_ptr< T > construct(Args &&...args)
Value & lookup_or_add_default(const Key &key)
bool add(const Key &key, const Value &value)
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)
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 is_volume_grid() const
GPointer get_single_ptr() const
const bNode * output_node
Vector< bNodeTreeZone * > child_zones
Vector< bNodeTreeZone * > root_zones
const FieldNode & node() const
FieldInfoLog(const GField &field)
GeoTreeLog & get_tree_log(const ComputeContextHash &compute_context_hash)
GeoTreeLogger & get_local_tree_logger(const ComputeContext &compute_context)
static Map< const bke::bNodeTreeZone *, GeoTreeLog * > get_tree_log_by_zone_for_node_editor(const SpaceNode &snode)
static const ViewerNodeLog * find_viewer_node_log_for_path(const ViewerPath &viewer_path)
static Map< const bke::bNodeTreeZone *, ComputeContextHash > get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name)
Vector< const GeometryAttributeInfo * > existing_attributes
void ensure_evaluated_gizmo_nodes()
void ensure_used_named_attributes()
VectorSet< NodeWarning > all_warnings
Set< int > evaluated_gizmo_nodes
void ensure_existing_attributes()
void ensure_socket_values()
void ensure_node_warnings(const bNodeTree *tree)
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()
GeoTreeLog(GeoModifierLog *modifier_log, Vector< GeoTreeLogger * > tree_loggers)
Map< int32_t, ViewerNodeLog *, 0 > viewer_node_logs
Map< StringRefNull, NamedAttributeUsage > used_named_attributes
Map< int32_t, GeoNodeLog > nodes
void ensure_debug_messages()
ValueLog * find_socket_value_log(const bNodeSocket &query_socket)
linear_allocator::ChunkedList< ViewerNodeLogWithNode > viewer_node_logs
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)
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
GeometryInfoLog(const bke::GeometrySet &geometry_set)
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
local_group_size(16, 16) .push_constant(Type b
static const char * modifier_name[LS_MODIFIER_NUM]
ccl_device_inline float3 log(float3 v)
VolumeGridType get_type(const VolumeGridData &grid)
bool attribute_name_is_anonymous(const StringRef name)
const DataTypeConversions & get_implicit_type_conversions()
Span< int > all_zone_output_node_types()
const GeoOperatorLog & node_group_operator_static_eval_log()
bool push_compute_context_for_tree_path(const SpaceNode &snode, ComputeContextBuilder &compute_context_builder)
std::optional< ObjectAndModifier > get_modifier_for_node_editor(const SpaceNode &snode)
bool add_compute_context_for_viewer_path_elem(const ViewerPathElem &elem, ComputeContextBuilder &compute_context_builder)
std::optional< ViewerPathForGeometryNodesViewer > parse_geometry_nodes_viewer(const ViewerPath &viewer_path)
int node_warning_type_icon(const NodeWarningType type)
int node_warning_type_severity(const NodeWarningType type)
static bool warning_is_propagated(const NodeWarningPropagation propagation, const NodeWarningType warning_type)
static void find_tree_zone_hash_recursive(const bNodeTreeZone &zone, ComputeContextBuilder &compute_context_builder, Map< const bNodeTreeZone *, ComputeContextHash > &r_hash_by_zone)
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
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
NamedAttributeUsage usage
StringRefNull attribute_name
destruct_ptr< ValueLog > value
destruct_ptr< ViewerNodeLog > viewer_log
bool has_deformed_positions