Files
test2/source/blender/nodes/geometry/node_geometry_util.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

116 lines
3.7 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
#include "node_geometry_util.hh"
#include "node_util.hh"
Geometry Nodes: Make instances real on-demand This commit makes the geometry output of the collection info usable. The output is the geometry of a collection instance, but this commit adds a utility to convert the instances to real geometry, used in the background whenever it is needed, like copy on write. The recursive nature of the "realize instances" code is essential, because collection instances in the `InstancesComponent`, might have no geometry sets of their own containing even more collection instances, which might then contain object instances, etc. Another consideration is that currently, every single instance contains a reference to its data. This is inefficient since most of the time there are many locations and only a few sets of unique data. So this commit adds a `GeometryInstanceGroup` to support this future optimization. The API for instances returns a vector of `GeometryInstanceGroup`. This may be less efficient when there are many instances, but it makes more complicated operations like point distribution that need to iterate over input geometry multiple times much simpler. Any code that needs to change data, like most of the attribute nodes, can simply call `geometry_set_realize_instances(geometry_set)`, which will move any geometry in the `InstancesComponent` to new "real" geometry components. Many nodes can support read-only access to instances in order to avoid making them real, this will be addressed where needed in the near future. Instances from the existing "dupli" system are not supported yet. Differential Revision: https://developer.blender.org/D10327
2021-02-12 11:58:15 -06:00
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_space_types.h"
Geometry Nodes: Make instances real on-demand This commit makes the geometry output of the collection info usable. The output is the geometry of a collection instance, but this commit adds a utility to convert the instances to real geometry, used in the background whenever it is needed, like copy on write. The recursive nature of the "realize instances" code is essential, because collection instances in the `InstancesComponent`, might have no geometry sets of their own containing even more collection instances, which might then contain object instances, etc. Another consideration is that currently, every single instance contains a reference to its data. This is inefficient since most of the time there are many locations and only a few sets of unique data. So this commit adds a `GeometryInstanceGroup` to support this future optimization. The API for instances returns a vector of `GeometryInstanceGroup`. This may be less efficient when there are many instances, but it makes more complicated operations like point distribution that need to iterate over input geometry multiple times much simpler. Any code that needs to change data, like most of the attribute nodes, can simply call `geometry_set_realize_instances(geometry_set)`, which will move any geometry in the `InstancesComponent` to new "real" geometry components. Many nodes can support read-only access to instances in order to avoid making them real, this will be addressed where needed in the near future. Instances from the existing "dupli" system are not supported yet. Differential Revision: https://developer.blender.org/D10327
2021-02-12 11:58:15 -06:00
#include "BKE_context.hh"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.hh"
#include "BKE_node.hh"
Geometry Nodes: Make instances real on-demand This commit makes the geometry output of the collection info usable. The output is the geometry of a collection instance, but this commit adds a utility to convert the instances to real geometry, used in the background whenever it is needed, like copy on write. The recursive nature of the "realize instances" code is essential, because collection instances in the `InstancesComponent`, might have no geometry sets of their own containing even more collection instances, which might then contain object instances, etc. Another consideration is that currently, every single instance contains a reference to its data. This is inefficient since most of the time there are many locations and only a few sets of unique data. So this commit adds a `GeometryInstanceGroup` to support this future optimization. The API for instances returns a vector of `GeometryInstanceGroup`. This may be less efficient when there are many instances, but it makes more complicated operations like point distribution that need to iterate over input geometry multiple times much simpler. Any code that needs to change data, like most of the attribute nodes, can simply call `geometry_set_realize_instances(geometry_set)`, which will move any geometry in the `InstancesComponent` to new "real" geometry components. Many nodes can support read-only access to instances in order to avoid making them real, this will be addressed where needed in the near future. Instances from the existing "dupli" system are not supported yet. Differential Revision: https://developer.blender.org/D10327
2021-02-12 11:58:15 -06:00
#include "BKE_pointcloud.h"
#include "NOD_rna_define.hh"
#include "NOD_socket_search_link.hh"
#include "RNA_enum_types.hh"
namespace blender::nodes {
bool check_tool_context_and_error(GeoNodeExecParams &params)
{
if (!params.user_data()->call_data->operator_data) {
params.error_message_add(NodeWarningType::Error, TIP_("Node must be run as tool"));
params.set_default_remaining_outputs();
return false;
}
return true;
}
void search_link_ops_for_tool_node(GatherLinkSearchOpParams &params)
{
if (params.space_node().geometry_nodes_type == SNODE_GEOMETRY_TOOL) {
search_link_ops_for_basic_node(params);
}
}
namespace enums {
const EnumPropertyItem *attribute_type_type_with_socket_fn(bContext * /*C*/,
PointerRNA * /*ptr*/,
PropertyRNA * /*prop*/,
bool *r_free)
{
*r_free = true;
return enum_items_filter(rna_enum_attribute_type_items,
[](const EnumPropertyItem &item) -> bool {
return generic_attribute_type_supported(item) &&
!ELEM(item.value, CD_PROP_BYTE_COLOR, CD_PROP_FLOAT2);
});
}
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,
CD_PROP_INT32,
CD_PROP_BYTE_COLOR,
CD_PROP_QUATERNION);
}
const EnumPropertyItem *domain_experimental_grease_pencil_version3_fn(bContext * /*C*/,
PointerRNA * /*ptr*/,
PropertyRNA * /*prop*/,
bool *r_free)
{
*r_free = true;
return enum_items_filter(
rna_enum_attribute_domain_items, [](const EnumPropertyItem &item) -> bool {
return (item.value == ATTR_DOMAIN_LAYER) ? U.experimental.use_grease_pencil_version3 :
true;
});
}
const EnumPropertyItem *domain_without_corner_experimental_grease_pencil_version3_fn(
bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free)
{
*r_free = true;
return enum_items_filter(
rna_enum_attribute_domain_without_corner_items, [](const EnumPropertyItem &item) -> bool {
return (item.value == ATTR_DOMAIN_LAYER) ? U.experimental.use_grease_pencil_version3 :
true;
});
}
} // namespace enums
} // namespace blender::nodes
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");
return false;
}
return true;
}
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
{
blender::bke::node_type_base(ntype, type, name, nclass);
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
ntype->poll = geo_node_poll_default;
ntype->insert_link = node_insert_link_default;
ntype->gather_link_search_ops = blender::nodes::search_link_ops_for_basic_node;
}