From 9b74290f688cd7d01b8f164a131285a3c0dbf796 Mon Sep 17 00:00:00 2001 From: Cedric Steiert Date: Fri, 19 Jul 2024 22:17:40 +0200 Subject: [PATCH 1/4] fix list index out of range for color_per_vertex fixes https://projects.blender.org/blender/blender-addons/issues/101604 by using the index position instead of the actual vertex value to access the rgb list. Now the file from mentioned issue can get imported, however in rendered view the colors are still missing. But that should probably be another issue, as it seems unrelated. --- source/import_x3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/import_x3d.py b/source/import_x3d.py index 4c21551..07e790e 100644 --- a/source/import_x3d.py +++ b/source/import_x3d.py @@ -1979,8 +1979,8 @@ def importMesh_IndexedFaceSet(geom, ancestry): d = bpymesh.vertex_colors.new().data if color_per_vertex: cco = [cco for f in processPerVertexIndex(color_index) - for v in f - for cco in rgb[v]] + for (i, v) in enumerate(f) + for cco in rgb[i]] elif color_index: # Color per face with index cco = [cco for (i, f) in enumerate(faces) for j in f -- 2.30.2 From 6cb7049fa31b47ffb99644911c0b9b464093f178 Mon Sep 17 00:00:00 2001 From: Cedric Steiert Date: Sat, 20 Jul 2024 17:02:18 +0200 Subject: [PATCH 2/4] fix detection of working wrl files Usually .wrl files with vertex colors have and colorIndex Field with -1 values as face end markers. In the original issue file no colorIndex Field was present, thus we check for 0 length, in which case a regular index count gets used. Now both issue file and correct file should import and display correctly. However to further bulletproof things, we should also check for invalid colorIndexes (without correct number of -1s), this still has to be done. --- source/import_x3d.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source/import_x3d.py b/source/import_x3d.py index 07e790e..da3e446 100644 --- a/source/import_x3d.py +++ b/source/import_x3d.py @@ -1975,12 +1975,19 @@ def importMesh_IndexedFaceSet(geom, ancestry): color_per_vertex = geom.getFieldAsBool('colorPerVertex', True, ancestry) color_index = geom.getFieldAsArray('colorIndex', 0, ancestry) + has_color_index = len(color_index) >= len(index) + # TODO: check color index for -1 values and rebuild if not existent d = bpymesh.vertex_colors.new().data - if color_per_vertex: + + if color_per_vertex and has_color_index: # Color per vertex with index cco = [cco for f in processPerVertexIndex(color_index) - for (i, v) in enumerate(f) - for cco in rgb[i]] + for v in f + for cco in rgb[v]] + elif color_per_vertex: # Color per vertex without index + cco = [cco for f in processPerVertexIndex(color_index) + for (i, v) in enumerate(f) + for cco in rgb[i]] elif color_index: # Color per face with index cco = [cco for (i, f) in enumerate(faces) for j in f -- 2.30.2 From e8e3c6454c02defbddb8a8eff99bf4f6636c2b16 Mon Sep 17 00:00:00 2001 From: Cedric Steiert Date: Sat, 20 Jul 2024 17:28:36 +0200 Subject: [PATCH 3/4] add colorIndex valid check and rebuild option for face end markers Now the code is able to: - rebuild colorIndex field if -1 face end markers are not matching with coordIndex - use regular index position if no colorIndex is given - handling vertex colors for both cases (with/without colorIndex) --- source/import_x3d.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/import_x3d.py b/source/import_x3d.py index da3e446..beb46e6 100644 --- a/source/import_x3d.py +++ b/source/import_x3d.py @@ -1975,11 +1975,20 @@ def importMesh_IndexedFaceSet(geom, ancestry): color_per_vertex = geom.getFieldAsBool('colorPerVertex', True, ancestry) color_index = geom.getFieldAsArray('colorIndex', 0, ancestry) - has_color_index = len(color_index) >= len(index) - # TODO: check color index for -1 values and rebuild if not existent + 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 + color_index = [x for x in color_index if x != -1] + # copy all -1 from coordIndex to colorIndex + for i, v in enumerate(index): + if v == -1: + color_index.insert(i, -1) + if color_per_vertex and has_color_index: # Color per vertex with index cco = [cco for f in processPerVertexIndex(color_index) for v in f -- 2.30.2 From 0f47714f591afd974e258b03362c3a12a46294de Mon Sep 17 00:00:00 2001 From: Cedric Steiert Date: Sun, 4 Aug 2024 23:19:45 +0200 Subject: [PATCH 4/4] simplify code for case Color per vertex without index as processPerVertexIndex(color_index) will default to returning faces for that case (as the color_index is empty), we can save the function call and provide the faces directly. --- source/import_x3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/import_x3d.py b/source/import_x3d.py index beb46e6..a086cb8 100644 --- a/source/import_x3d.py +++ b/source/import_x3d.py @@ -1994,7 +1994,7 @@ def importMesh_IndexedFaceSet(geom, ancestry): for v in f for cco in rgb[v]] elif color_per_vertex: # Color per vertex without index - cco = [cco for f in processPerVertexIndex(color_index) + cco = [cco for f in faces for (i, v) in enumerate(f) for cco in rgb[i]] elif color_index: # Color per face with index -- 2.30.2