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.

  • 2
    $\begingroup$ You could use Python to convert edge data into attributes in edge domain. $\endgroup$ Dec 11, 2022 at 11:40
  • $\begingroup$ Thank you -- I found a solution by doing that! I will post it up as an answer. $\endgroup$
    – user159149
    Dec 11, 2022 at 13:28

1 Answer 1


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():
    # 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)


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):
        return {'FINISHED'}
def menu_func(self, context):
    self.layout.operator(ApplyFreestyleAttributeOperator.bl_idname, text=ApplyFreestyleAttributeOperator.bl_label)


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .