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 fd2106afa5 - Show all commits

View File

@ -1957,7 +1957,11 @@ def importMesh_IndexedFaceSet(geom, ancestry):
co = [co for f in processPerVertexIndex(normal_index)
for v in f
for co in vectors[v]]
bpymesh.vertices.foreach_set("normal", co)
# Mesh must be validated before assigning normals, but validation might
# reorder corners. We must store normals in a temporary attribute
bpymesh.attributes.new("temp_custom_normals", 'FLOAT_VECTOR', 'CORNER')
bpymesh.attributes["temp_custom_normals"].data.foreach_set("vector", co)
else:
co = [co for (i, f) in enumerate(faces)
for j in f
@ -1981,6 +1985,11 @@ def importMesh_IndexedFaceSet(geom, ancestry):
cco = [cco for f in processPerVertexIndex(color_index)
for v in f
for cco in rgb[v]]
# 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)
elif color_index: # Color per face with index
cco = [cco for (i, f) in enumerate(faces)
for j in f
@ -2039,7 +2048,38 @@ def importMesh_IndexedFaceSet(geom, ancestry):
importMesh_ApplyTextureToLoops(bpymesh, loops)
bpymesh.validate()
# Validating the mesh
if (normals and per_vertex) or (colors and color_per_vertex):
bpymesh.validate(clean_customdata=False)
# Apply normals per vertex
if normals and per_vertex:
# Get normals back to a list
co2 = [0.0 for x in range(int(len(bpymesh.attributes["temp_custom_normals"].data)*3))]
bpymesh.attributes["temp_custom_normals"].data.foreach_get("vector", co2)
# Use that list to set normals
bpymesh.normals_split_custom_set(tuple(zip(*(iter(co2),) * 3)))
# And delete the temporary attribute
bpymesh.attributes.remove(bpymesh.attributes["temp_custom_normals"])
# bpymesh.shade_smooth()
# Apply colors per vertex
if colors and color_per_vertex:
# Get normals back to a list
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)
# Use that list to set per vertex colors
# bpymesh.color_attributes.new("Col", 'FLOAT_COLOR', 'CORNER');
bpymesh.color_attributes["Col"].data.foreach_set("color", cco2)
# And delete the temporary attribute
bpymesh.attributes.remove(bpymesh.attributes["temp_custom_colors"])
else:
bpymesh.validate()
bpymesh.update()
return bpymesh
@ -2710,10 +2750,9 @@ def appearance_CreateMaterial(vrmlname, mat, ancestry, is_vcol):
bpymat.blend_method = "BLEND"
bpymat.shadow_method = "HASHED"
# NOTE - leaving this disabled for now
if False and is_vcol:
if is_vcol:
node_vertex_color = bpymat.node_tree.nodes.new("ShaderNodeVertexColor")
node_vertex_color.location = (-200, 300)
node_vertex_color.layer_name = "Col"
bpymat.node_tree.links.new(
bpymat_wrap.node_principled_bsdf.inputs["Base Color"],