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.hh14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc190
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc57
4 files changed, 221 insertions, 60 deletions
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index f278d6b4107..3820c0f0009 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -24,6 +24,8 @@
#include "DNA_node_types.h"
+struct Depsgraph;
+
namespace blender::nodes {
using bke::BooleanReadAttribute;
@@ -54,18 +56,21 @@ class GeoNodeExecParams {
GValueMap<StringRef> &output_values_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
+ Depsgraph *depsgraph_;
public:
GeoNodeExecParams(const bNode &node,
GValueMap<StringRef> &input_values,
GValueMap<StringRef> &output_values,
const PersistentDataHandleMap &handle_map,
- const Object *self_object)
+ const Object *self_object,
+ Depsgraph *depsgraph)
: node_(node),
input_values_(input_values),
output_values_(output_values),
handle_map_(handle_map),
- self_object_(self_object)
+ self_object_(self_object),
+ depsgraph_(depsgraph)
{
}
@@ -163,6 +168,11 @@ class GeoNodeExecParams {
return self_object_;
}
+ Depsgraph *depsgraph() const
+ {
+ return depsgraph_;
+ }
+
/**
* Creates a read-only attribute based on node inputs. The method automatically detects which
* input with the given name is available.
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 0e7bb25e659..3ee7df7fe72 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
@@ -50,8 +50,7 @@ static void geo_node_attribute_randomize_update(bNodeTree *UNUSED(ntree), bNode
bNodeSocket *sock_min_float = sock_max_vector->next;
bNodeSocket *sock_max_float = sock_min_float->next;
- const int data_type = node->custom1;
-
+ const CustomDataType data_type = static_cast<CustomDataType>(node->custom1);
nodeSetSocketAvailability(sock_min_vector, data_type == CD_PROP_FLOAT3);
nodeSetSocketAvailability(sock_max_vector, data_type == CD_PROP_FLOAT3);
nodeSetSocketAvailability(sock_min_float, data_type == CD_PROP_FLOAT);
@@ -86,8 +85,11 @@ static void randomize_attribute_bool(BooleanWriteAttribute attribute,
attribute.apply_span();
}
-static void randomize_attribute_float(
- FloatWriteAttribute attribute, float min, float max, Span<uint32_t> hashes, const int seed)
+static void randomize_attribute_float(FloatWriteAttribute attribute,
+ const float min,
+ const float max,
+ Span<uint32_t> hashes,
+ const int seed)
{
MutableSpan<float> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@@ -97,8 +99,11 @@ static void randomize_attribute_float(
attribute.apply_span();
}
-static void randomize_attribute_float3(
- Float3WriteAttribute attribute, float3 min, float3 max, Span<uint32_t> hashes, const int seed)
+static void randomize_attribute_float3(Float3WriteAttribute attribute,
+ const float3 min,
+ const float3 max,
+ Span<uint32_t> hashes,
+ const int seed)
{
MutableSpan<float3> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@@ -129,8 +134,7 @@ Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &compo
}
else {
/* If there is no "id" attribute for per-point variation, just create it here. */
- RandomNumberGenerator rng;
- rng.seed(0);
+ RandomNumberGenerator rng(0);
for (const int i : hashes.index_range()) {
hashes[i] = rng.get_uint32();
}
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 2f1aa276532..eaf13b94eb9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -26,6 +26,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
+#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
@@ -217,13 +218,141 @@ BLI_NOINLINE static void eliminate_points_based_on_mask(Span<bool> elimination_m
}
}
-BLI_NOINLINE static void compute_remaining_point_data(const Mesh &mesh,
- Span<float3> bary_coords,
- Span<int> looptri_indices,
- MutableSpan<float3> r_normals,
- MutableSpan<int> r_ids,
- MutableSpan<float3> r_rotations)
+template<typename T>
+BLI_NOINLINE static void interpolate_attribute_point(const Mesh &mesh,
+ const Span<float3> bary_coords,
+ const Span<int> looptri_indices,
+ const Span<T> data_in,
+ MutableSpan<T> data_out)
{
+ BLI_assert(data_in.size() == mesh.totvert);
+ Span<MLoopTri> looptris = get_mesh_looptris(mesh);
+
+ for (const int i : bary_coords.index_range()) {
+ const int looptri_index = looptri_indices[i];
+ const MLoopTri &looptri = looptris[looptri_index];
+ const float3 &bary_coord = bary_coords[i];
+
+ const int v0_index = mesh.mloop[looptri.tri[0]].v;
+ const int v1_index = mesh.mloop[looptri.tri[1]].v;
+ const int v2_index = mesh.mloop[looptri.tri[2]].v;
+
+ const T &v0 = data_in[v0_index];
+ const T &v1 = data_in[v1_index];
+ const T &v2 = data_in[v2_index];
+
+ const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
+ data_out[i] = interpolated_value;
+ }
+}
+
+template<typename T>
+BLI_NOINLINE static void interpolate_attribute_corner(const Mesh &mesh,
+ const Span<float3> bary_coords,
+ const Span<int> looptri_indices,
+ const Span<T> data_in,
+ MutableSpan<T> data_out)
+{
+ BLI_assert(data_in.size() == mesh.totloop);
+ Span<MLoopTri> looptris = get_mesh_looptris(mesh);
+
+ for (const int i : bary_coords.index_range()) {
+ const int looptri_index = looptri_indices[i];
+ const MLoopTri &looptri = looptris[looptri_index];
+ const float3 &bary_coord = bary_coords[i];
+
+ const int loop_index_0 = looptri.tri[0];
+ const int loop_index_1 = looptri.tri[1];
+ const int loop_index_2 = looptri.tri[2];
+
+ const T &v0 = data_in[loop_index_0];
+ const T &v1 = data_in[loop_index_1];
+ const T &v2 = data_in[loop_index_2];
+
+ const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
+ data_out[i] = interpolated_value;
+ }
+}
+
+BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices,
+ const StringRef attribute_name,
+ const ReadAttribute &attribute_in,
+ GeometryComponent &component)
+{
+ const CustomDataType data_type = attribute_in.custom_data_type();
+ const AttributeDomain domain = attribute_in.domain();
+ if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
+ /* Not supported currently. */
+ return;
+ }
+
+ OutputAttributePtr attribute_out = component.attribute_try_get_for_output(
+ attribute_name, ATTR_DOMAIN_POINT, data_type);
+ if (!attribute_out) {
+ return;
+ }
+
+ attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+
+ Span data_in = attribute_in.get_span<T>();
+ MutableSpan data_out = attribute_out->get_span_for_write_only<T>();
+
+ switch (domain) {
+ case ATTR_DOMAIN_POINT: {
+ interpolate_attribute_point<T>(mesh, bary_coords, looptri_indices, data_in, data_out);
+ break;
+ }
+ case ATTR_DOMAIN_CORNER: {
+ interpolate_attribute_corner<T>(mesh, bary_coords, looptri_indices, data_in, data_out);
+ break;
+ }
+ default: {
+ BLI_assert(false);
+ break;
+ }
+ }
+ });
+ attribute_out.apply_span_and_save();
+}
+
+BLI_NOINLINE static void interpolate_existing_attributes(const MeshComponent &mesh_component,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ const Mesh &mesh = *mesh_component.get_for_read();
+
+ Set<std::string> attribute_names = mesh_component.attribute_names();
+ for (StringRefNull attribute_name : attribute_names) {
+ if (ELEM(attribute_name, "position", "normal", "id")) {
+ continue;
+ }
+
+ ReadAttributePtr attribute_in = mesh_component.attribute_try_get_for_read(attribute_name);
+ interpolate_attribute(
+ mesh, bary_coords, looptri_indices, attribute_name, *attribute_in, component);
+ }
+}
+
+BLI_NOINLINE static void compute_special_attributes(const Mesh &mesh,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ OutputAttributePtr id_attribute = component.attribute_try_get_for_output(
+ "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
+ OutputAttributePtr normal_attribute = component.attribute_try_get_for_output(
+ "normal", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+ OutputAttributePtr rotation_attribute = component.attribute_try_get_for_output(
+ "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+
+ MutableSpan<int> ids = id_attribute->get_span_for_write_only<int>();
+ MutableSpan<float3> normals = normal_attribute->get_span_for_write_only<float3>();
+ MutableSpan<float3> rotations = rotation_attribute->get_span_for_write_only<float3>();
+
Span<MLoopTri> looptris = get_mesh_looptris(mesh);
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
@@ -237,10 +366,24 @@ BLI_NOINLINE static void compute_remaining_point_data(const Mesh &mesh,
const float3 v1_pos = mesh.mvert[v1_index].co;
const float3 v2_pos = mesh.mvert[v2_index].co;
- r_ids[i] = (int)(bary_coord.hash()) + looptri_index;
- normal_tri_v3(r_normals[i], v0_pos, v1_pos, v2_pos);
- r_rotations[i] = normal_to_euler_rotation(r_normals[i]);
+ ids[i] = (int)(bary_coord.hash()) + looptri_index;
+ normal_tri_v3(normals[i], v0_pos, v1_pos, v2_pos);
+ rotations[i] = normal_to_euler_rotation(normals[i]);
}
+
+ id_attribute.apply_span_and_save();
+ normal_attribute.apply_span_and_save();
+ rotation_attribute.apply_span_and_save();
+}
+
+BLI_NOINLINE static void add_remaining_point_attributes(const MeshComponent &mesh_component,
+ GeometryComponent &component,
+ Span<float3> bary_coords,
+ Span<int> looptri_indices)
+{
+ interpolate_existing_attributes(mesh_component, component, bary_coords, looptri_indices);
+ compute_special_attributes(
+ *mesh_component.get_for_read(), component, bary_coords, looptri_indices);
}
static void sample_mesh_surface_with_minimum_distance(const Mesh &mesh,
@@ -315,11 +458,6 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
break;
}
const int tot_points = positions.size();
- Array<float3> normals(tot_points);
- Array<int> stable_ids(tot_points);
- Array<float3> rotations(tot_points);
- compute_remaining_point_data(
- *mesh_in, bary_coords, looptri_indices, normals, stable_ids, rotations);
PointCloud *pointcloud = BKE_pointcloud_new_nomain(tot_points);
memcpy(pointcloud->co, positions.data(), sizeof(float3) * tot_points);
@@ -332,29 +470,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
geometry_set_out.get_component_for_write<PointCloudComponent>();
point_component.replace(pointcloud);
- {
- OutputAttributePtr stable_id_attribute = point_component.attribute_try_get_for_output(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
- MutableSpan<int> stable_ids_span = stable_id_attribute->get_span<int>();
- stable_ids_span.copy_from(stable_ids);
- stable_id_attribute.apply_span_and_save();
- }
-
- {
- OutputAttributePtr normals_attribute = point_component.attribute_try_get_for_output(
- "normal", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- MutableSpan<float3> normals_span = normals_attribute->get_span<float3>();
- normals_span.copy_from(normals);
- normals_attribute.apply_span_and_save();
- }
-
- {
- OutputAttributePtr rotations_attribute = point_component.attribute_try_get_for_output(
- "rotation", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
- MutableSpan<float3> rotations_span = rotations_attribute->get_span<float3>();
- rotations_span.copy_from(rotations);
- rotations_attribute.apply_span_and_save();
- }
+ add_remaining_point_attributes(mesh_component, point_component, bary_coords, looptri_indices);
params.set_output("Geometry", std::move(geometry_set_out));
}
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index 2e4196af156..33192648d93 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -19,6 +19,7 @@
#include "FN_multi_function_network_evaluation.hh"
#include "BLI_color.hh"
+#include "BLI_float2.hh"
#include "BLI_float3.hh"
namespace blender::nodes {
@@ -191,27 +192,57 @@ static void add_implicit_conversion(DataTypeConversions &conversions,
static DataTypeConversions create_implicit_conversions()
{
DataTypeConversions conversions;
- add_implicit_conversion<float, int32_t>(conversions);
+ add_implicit_conversion<float, float2>(conversions);
add_implicit_conversion<float, float3>(conversions);
- add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<float, int32_t>(conversions);
add_implicit_conversion<float, bool>(conversions);
- add_implicit_conversion<bool, float>(conversions);
- add_implicit_conversion<float3, float>(
- conversions, "Vector Length", [](float3 a) { return a.length(); });
- add_implicit_conversion<int32_t, float3>(
- conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
- add_implicit_conversion<float3, Color4f>(
- conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
- add_implicit_conversion<Color4f, float3>(
- conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
add_implicit_conversion<float, Color4f>(
conversions, "float to Color4f", [](float a) { return Color4f(a, a, a, 1.0f); });
- add_implicit_conversion<Color4f, float>(
- conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
+
+ add_implicit_conversion<float2, float3>(conversions);
+ add_implicit_conversion<float2, float>(
+ conversions, "float2 to float", [](float2 a) { return a.length(); });
+ add_implicit_conversion<float2, int32_t>(
+ conversions, "float2 to int32_t", [](float2 a) { return (int32_t)a.length(); });
+ add_implicit_conversion<float2, bool>(
+ conversions, "float2 to bool", [](float2 a) { return a.length_squared() == 0.0f; });
+ add_implicit_conversion<float2, Color4f>(
+ conversions, "float2 to Color4f", [](float2 a) { return Color4f(a.x, a.y, 0.0f, 1.0f); });
+
add_implicit_conversion<float3, bool>(
conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; });
+ add_implicit_conversion<float3, float>(
+ conversions, "Vector Length", [](float3 a) { return a.length(); });
+ add_implicit_conversion<float3, int32_t>(
+ conversions, "float3 to int32_t", [](float3 a) { return (int)a.length(); });
+ add_implicit_conversion<float3, float2>(conversions);
+ add_implicit_conversion<float3, Color4f>(
+ conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
+
+ add_implicit_conversion<int32_t, bool>(conversions);
+ add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<int32_t, float2>(
+ conversions, "int32 to float2", [](int32_t a) { return float2((float)a); });
+ add_implicit_conversion<int32_t, float3>(
+ conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
+
+ add_implicit_conversion<bool, float>(conversions);
+ add_implicit_conversion<bool, int32_t>(conversions);
+ add_implicit_conversion<bool, float2>(
+ conversions, "boolean to float2", [](bool a) { return (a) ? float2(1.0f) : float2(0.0f); });
add_implicit_conversion<bool, float3>(
conversions, "boolean to float3", [](bool a) { return (a) ? float3(1.0f) : float3(0.0f); });
+ add_implicit_conversion<bool, Color4f>(conversions, "boolean to Color4f", [](bool a) {
+ return (a) ? Color4f(1.0f, 1.0f, 1.0f, 1.0f) : Color4f(0.0f, 0.0f, 0.0f, 1.0f);
+ });
+
+ add_implicit_conversion<Color4f, float>(
+ conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
+ add_implicit_conversion<Color4f, float2>(
+ conversions, "Color4f to float2", [](Color4f a) { return float2(a.r, a.g); });
+ add_implicit_conversion<Color4f, float3>(
+ conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
+
return conversions;
}