So here’s slightly more sophisticated (but still a bit crappy) version:
class OBJECT_OT_ConvertAttributeUVMap(bpy.types.Operator):
"""Converst first found face corner attribuet to UVMap"""
bl_idname = "object.convert_attribute_uvmap"
bl_label = "Convert fist face corner attribute to UV Map"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
source_name = context.active_object.name
# Duplicate active object
bpy.ops.object.duplicate()
# Collapse existing modifiers on the mesh object
bpy.ops.object.convert(target='MESH')
# Store and name the duplicated object
obj = context.active_object
obj.name = source_name + "_Baked"
# Create UVMap UV layer if there's none present
if obj.data.uv_layers.find("UVMap") == -1:
uvmap = obj.data.uv_layers.new(name="UVMap")
else:
uvmap_index = obj.data.uv_layers.find("UVMap")
uvmap = obj.data.uv_layers[uvmap_index]
# UV attribute to store
uv_attrib = None
# Try to find valid face corner attribute
for attribute in obj.data.attributes:
if attribute.domain == 'CORNER':
uv_attrib = attribute
# Check if face corner attribute was found
if uv_attrib is None:
if context.active_object is obj:
bpy.ops.object.delete()
self.report({'ERROR'}, 'No Face Corner attribute found!')
return {'CANCELLED'}
for loop in obj.data.loops:
uvmap.data[loop.index].uv[0] = uv_attrib.data[loop.index].vector[0]
uvmap.data[loop.index].uv[1] = uv_attrib.data[loop.index].vector[1]
obj.data.attributes.remove(uv_attrib)
return {'FINISHED'}
It will find first face corner attribute and turn it into a UVMap, either creating or overriding UVMap channel. This is still bad as it assumes that there is only one Attribute Capture node set to Face Corner domain in the GN network, and that it’s used for UVs, so if someone needed to use Attribute Capture set to face corner multiple times for something else, it’d fail.
I am still curious if there’s a way to gather the attribute vector values using foreach_get and then dump them into the UV map using foreach_get. The face corner attribute is 3D vector while the UV map channel seems to expect 2D vector, so IDK how to do that.