7

I would like to mark certain edges with custom data, similar to Vertex Groups, and import that Selection into my Geometry Nodes setup to operate on only those specified edges.

This is already possible with the edge's crease, but that seems to be the only exposed data. Can I...

  • Create custom Edge Groups, like Vertex Groups, and import those?
  • Import Freestyle-marked edges, just like crease?
  • Import marked UV Seams, just like crease?
  • ... or hack some other solution, with scripting or custom data?

I am currently using crease, but I want to move to a solution that doesn't conflict with Subdivision Surface.

user159149
  • 181
  • 6

1 Answers1

11

Solved with a Python script to convert edge data into edge-domain attributes:

import bpy

if in non-object mode, swap to object mode and back to apply changes

def refresh(): m = bpy.context.mode if bpy.context.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT') if bpy.context.mode != m: bpy.ops.object.mode_set(mode=m)

def apply_freestyle_attribute(): refresh()

# apply to selection
for object in bpy.context.selected_objects:
    mesh = object.data

    # create the attribute if it doesn't exist
    if (mesh.attributes.find("freestyle_edge") == -1):
        mesh.attributes.new(name="freestyle_edge", type="BOOLEAN", domain="EDGE")

    # assign the attribute's bool value to the freestyle value
    attribute_values = [edge.use_freestyle_mark for edge in mesh.edges]
    mesh.attributes["freestyle_edge"].data.foreach_set("value", attribute_values)

apply_freestyle_attribute()

After running this script, the attribute freestyle_edge will be present on any selected objects, and filled with freestyle edge data. The script can be modified to use sharp markings or UV seams as necessary.

That attribute can then be imported into the geometry nodes' Group Input node via a Selection parameter, and specified in the modifier settings.

To make it an operator, add this code:

class ApplyFreestyleAttributeOperator(bpy.types.Operator):
    bl_idname = "wm.apply_freestyle_attribute"
    bl_label = "Apply Freestyle Attribute"
def execute(self, context):
    apply_freestyle_attribute()
    return {'FINISHED'}


def menu_func(self, context): self.layout.operator(ApplyFreestyleAttributeOperator.bl_idname, text=ApplyFreestyleAttributeOperator.bl_label)

bpy.utils.register_class(ApplyFreestyleAttributeOperator) bpy.types.VIEW3D_MT_view.append(menu_func)

Chris
  • 59,454
  • 6
  • 30
  • 84
user159149
  • 181
  • 6