Fix per vertex normals and colors import #6

Merged
Cedric Steiert merged 10 commits from Hombre57/io_scene_x3d:per-vertex_normals_and_colors into main 2024-08-07 12:04:13 +02:00
Showing only changes of commit c957f6bc57 - Show all commits

View File

@ -1996,8 +1996,6 @@ def importMesh_IndexedFaceSet(geom, ancestry):
has_color_index = len(color_index) != 0
has_valid_color_index = index.count(-1) == color_index.count(-1)
d = bpymesh.vertex_colors.new().data
# rebuild a corrupted colorIndex field (assuming the end of face markers -1 are missing)
if has_color_index and not has_valid_color_index:
# remove all -1 beforehand to ensure clean working copy
@ -2028,14 +2026,15 @@ def importMesh_IndexedFaceSet(geom, ancestry):
cco = [cco for (i, f) in enumerate(faces)
for j in f
for cco in rgb[i]]
d.foreach_set('color', cco)
if color_per_vertex:
# Mesh must be validated before assigning colors, but validation might
# reorder corners. We must store colors in a temporary attribute
bpymesh.attributes.new("temp_custom_colors", 'FLOAT_COLOR', 'CORNER')
bpymesh.attributes["temp_custom_colors"].data.foreach_set("color", cco)
else:
d = bpymesh.vertex_colors.new().data
d.foreach_set('color', cco)
# Texture coordinates (UVs)
tex_coord = geom.getChildBySpec('TextureCoordinate')
@ -2094,10 +2093,24 @@ def importMesh_IndexedFaceSet(geom, ancestry):
bpymesh.normals_split_custom_set(tuple(zip(*(iter(co2),) * 3)))
bpymesh.attributes.remove(bpymesh.attributes["temp_custom_normals"])
def linear_to_srgb(linear):
if linear <= 0.0031308:
return linear * 12.92
else:
return 1.055 * (linear ** (1.0 / 2.4)) - 0.055
def srgb_to_linear(srgb_value):
if srgb_value <= 0.04045:
return srgb_value / 12.92
else:
return ((srgb_value + 0.055) / 1.055) ** 2.4
# Apply colors per vertex
if colors and color_per_vertex:
cco2 = [0.0 for x in range(int(len(bpymesh.attributes["temp_custom_colors"].data)*4))]
bpymesh.attributes["temp_custom_colors"].data.foreach_get("color", cco2)
# convert color spaces to account for api changes
cco2 = [srgb_to_linear(col_val) for col_val in cco2]
bpymesh.color_attributes.new('ColorPerCorner', 'FLOAT_COLOR', 'CORNER')
bpymesh.color_attributes["ColorPerCorner"].data.foreach_set("color", cco2)
bpymesh.attributes.remove(bpymesh.attributes["temp_custom_colors"])