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)