diff options
author | Philipp Oeser <info@graphics-engineer.com> | 2022-04-04 13:26:50 +0300 |
---|---|---|
committer | Philipp Oeser <info@graphics-engineer.com> | 2022-06-16 21:34:27 +0300 |
commit | e2975cb701692574504967178699c9ab083dc3f8 (patch) | |
tree | 835f1bb625607b2595bfdecf364b97070c3f67a5 /source/blender/nodes | |
parent | 209bf7780e7c005650482fa843062864f91845af (diff) |
Geometry Nodes: add 'Intersecting Edges' output for boolean node
This patch adds a 'Intersecting Edges' output with a boolean selection
that only gives you the new edges on intersections.
Will work on a couple of examples next, this should make some
interesting effects possible (including getting us closer to the "bevel-
after-boolean-usecase")
To achieve this, a Vector is passed to `direct_mesh_boolean` when the
iMesh is still available (and intersecting edges appended), then from
those edge indices a selection will be stored as attribute.
Differential Revision: https://developer.blender.org/D15151
Diffstat (limited to 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_boolean.cc | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc index e485172d3e1..daeca311e08 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc @@ -20,6 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input<decl::Bool>(N_("Self Intersection")); b.add_input<decl::Bool>(N_("Hole Tolerant")); b.add_output<decl::Geometry>(N_("Mesh")); + b.add_output<decl::Bool>(N_("Intersecting Edges")).field_source(); } static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -27,6 +28,10 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); } +struct AttributeOutputs { + StrongAnonymousAttributeID intersecting_edges_id; +}; + static void node_update(bNodeTree *ntree, bNode *node) { GeometryNodeBooleanOperation operation = (GeometryNodeBooleanOperation)node->custom1; @@ -121,13 +126,21 @@ static void node_geo_exec(GeoNodeExecParams params) } } - Mesh *result = blender::meshintersect::direct_mesh_boolean(meshes, - transforms, - float4x4::identity(), - material_remaps, - use_self, - hole_tolerant, - operation); + AttributeOutputs attribute_outputs; + if (params.output_is_required("Intersecting Edges")) { + attribute_outputs.intersecting_edges_id = StrongAnonymousAttributeID("Intersecting Edges"); + } + + Vector<int> intersecting_edges; + Mesh *result = blender::meshintersect::direct_mesh_boolean( + meshes, + transforms, + float4x4::identity(), + material_remaps, + use_self, + hole_tolerant, + operation, + attribute_outputs.intersecting_edges_id ? &intersecting_edges : nullptr); if (!result) { params.set_default_remaining_outputs(); return; @@ -138,6 +151,26 @@ static void node_geo_exec(GeoNodeExecParams params) result->totcol = materials.size(); MutableSpan(result->mat, result->totcol).copy_from(materials); + /* Store intersecting edges in attribute. */ + if (attribute_outputs.intersecting_edges_id) { + MeshComponent mesh_component; + mesh_component.replace(result, GeometryOwnershipType::Editable); + OutputAttribute_Typed<bool> attribute = mesh_component.attribute_try_get_for_output_only<bool>( + attribute_outputs.intersecting_edges_id.get(), ATTR_DOMAIN_EDGE); + MutableSpan<bool> selection = attribute.as_span(); + selection.fill(false); + for (const int i : intersecting_edges) { + selection[i] = true; + } + + attribute.save(); + + params.set_output( + "Intersecting Edges", + AnonymousAttributeFieldInput::Create<bool>( + std::move(attribute_outputs.intersecting_edges_id), params.attribute_producer_name())); + } + params.set_output("Mesh", GeometrySet::create_with_mesh(result)); #else params.error_message_add(NodeWarningType::Error, |