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:
-rw-r--r--release/scripts/startup/bl_ui/node_add_menu_geometry.py2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc130
2 files changed, 85 insertions, 47 deletions
diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py
index fd218165357..e1b57ec4f43 100644
--- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py
+++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py
@@ -208,6 +208,7 @@ class NODE_MT_geometry_node_GEO_MESH(Menu):
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
+ node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")
@@ -244,7 +245,6 @@ class NODE_MT_geometry_node_mesh_topology(Menu):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace"),
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex"),
- node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner"),
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfVertex"),
node_add_menu.add_node_type(layout, "GeometryNodeFaceOfCorner"),
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
index 8d5b1432d53..149d44b2207 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
@@ -11,33 +11,35 @@ namespace blender::nodes::node_geo_input_mesh_edge_vertices_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Int>(N_("Edge Index"))
- .implicit_field(implicit_field_inputs::index)
- .description(N_("The edge to retrieve data from. Defaults to the edge from the context"));
b.add_output<decl::Int>(N_("Vertex Index 1"))
- .dependent_field()
+ .field_source()
.description(N_("The index of the first vertex in the edge"));
b.add_output<decl::Int>(N_("Vertex Index 2"))
- .dependent_field()
+ .field_source()
.description(N_("The index of the second vertex in the edge"));
b.add_output<decl::Vector>(N_("Position 1"))
- .dependent_field()
+ .field_source()
.description(N_("The position of the first vertex in the edge"));
b.add_output<decl::Vector>(N_("Position 2"))
- .dependent_field()
+ .field_source()
.description(N_("The position of the second vertex in the edge"));
}
enum class VertNumber { V1, V2 };
-static int edge_get_v1(const MEdge &edge)
+static VArray<int> construct_edge_verts_gvarray(const Mesh &mesh,
+ const VertNumber vertex,
+ const eAttrDomain domain)
{
- return edge.v1;
-}
-
-static int edge_get_v2(const MEdge &edge)
-{
- return edge.v2;
+ const Span<MEdge> edges = mesh.edges();
+ if (domain == ATTR_DOMAIN_EDGE) {
+ if (vertex == VertNumber::V1) {
+ return VArray<int>::ForFunc(edges.size(),
+ [edges](const int i) -> int { return edges[i].v1; });
+ }
+ return VArray<int>::ForFunc(edges.size(), [edges](const int i) -> int { return edges[i].v2; });
+ }
+ return {};
}
class EdgeVertsInput final : public bke::MeshFieldInput {
@@ -55,17 +57,7 @@ class EdgeVertsInput final : public bke::MeshFieldInput {
const eAttrDomain domain,
const IndexMask /*mask*/) const final
{
- if (domain != ATTR_DOMAIN_EDGE) {
- return {};
- }
- switch (vertex_) {
- case VertNumber::V1:
- return VArray<int>::ForDerivedSpan<MEdge, edge_get_v1>(mesh.edges());
- case VertNumber::V2:
- return VArray<int>::ForDerivedSpan<MEdge, edge_get_v2>(mesh.edges());
- }
- BLI_assert_unreachable();
- return {};
+ return construct_edge_verts_gvarray(mesh, vertex_, domain);
}
uint64_t hash() const override
@@ -87,30 +79,76 @@ class EdgeVertsInput final : public bke::MeshFieldInput {
}
};
-static void node_geo_exec(GeoNodeExecParams params)
+static VArray<float3> construct_edge_positions_gvarray(const Mesh &mesh,
+ const VertNumber vertex,
+ const eAttrDomain domain)
{
- const Field<int> edge_index = params.extract_input<Field<int>>("Edge Index");
- Field<int> vertex_field_1(std::make_shared<FieldAtIndexInput>(
- edge_index, Field<int>(std::make_shared<EdgeVertsInput>(VertNumber::V1)), ATTR_DOMAIN_EDGE));
- Field<int> vertex_field_2(std::make_shared<FieldAtIndexInput>(
- edge_index, Field<int>(std::make_shared<EdgeVertsInput>(VertNumber::V2)), ATTR_DOMAIN_EDGE));
-
- params.set_output("Vertex Index 1", vertex_field_1);
- params.set_output("Vertex Index 2", vertex_field_2);
- if (params.output_is_required("Position 1")) {
- params.set_output("Position 1",
- Field<float3>(std::make_shared<FieldAtIndexInput>(
- vertex_field_1,
- Field<float3>(AttributeFieldInput::Create<float3>("position")),
- ATTR_DOMAIN_POINT)));
+ const Span<MVert> verts = mesh.verts();
+ const Span<MEdge> edges = mesh.edges();
+
+ if (vertex == VertNumber::V1) {
+ return mesh.attributes().adapt_domain<float3>(
+ VArray<float3>::ForFunc(edges.size(),
+ [verts, edges](const int i) { return verts[edges[i].v1].co; }),
+ ATTR_DOMAIN_EDGE,
+ domain);
}
- if (params.output_is_required("Position 2")) {
- params.set_output("Position 2",
- Field<float3>(std::make_shared<FieldAtIndexInput>(
- vertex_field_2,
- Field<float3>(AttributeFieldInput::Create<float3>("position")),
- ATTR_DOMAIN_POINT)));
+ return mesh.attributes().adapt_domain<float3>(
+ VArray<float3>::ForFunc(edges.size(),
+ [verts, edges](const int i) { return verts[edges[i].v2].co; }),
+ ATTR_DOMAIN_EDGE,
+ domain);
+}
+
+class EdgePositionFieldInput final : public bke::MeshFieldInput {
+ private:
+ VertNumber vertex_;
+
+ public:
+ EdgePositionFieldInput(VertNumber vertex)
+ : bke::MeshFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const Mesh &mesh,
+ const eAttrDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ return construct_edge_positions_gvarray(mesh, vertex_, domain);
}
+
+ uint64_t hash() const override
+ {
+ return vertex_ == VertNumber::V1 ? 987456978362 : 374587679866;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ if (const EdgePositionFieldInput *other_field = dynamic_cast<const EdgePositionFieldInput *>(
+ &other)) {
+ return vertex_ == other_field->vertex_;
+ }
+ return false;
+ }
+
+ std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
+ {
+ return ATTR_DOMAIN_EDGE;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> vertex_field_1{std::make_shared<EdgeVertsInput>(VertNumber::V1)};
+ Field<int> vertex_field_2{std::make_shared<EdgeVertsInput>(VertNumber::V2)};
+ Field<float3> position_field_1{std::make_shared<EdgePositionFieldInput>(VertNumber::V1)};
+ Field<float3> position_field_2{std::make_shared<EdgePositionFieldInput>(VertNumber::V2)};
+
+ params.set_output("Vertex Index 1", std::move(vertex_field_1));
+ params.set_output("Vertex Index 2", std::move(vertex_field_2));
+ params.set_output("Position 1", std::move(position_field_1));
+ params.set_output("Position 2", std::move(position_field_2));
}
} // namespace blender::nodes::node_geo_input_mesh_edge_vertices_cc