From 1d5d0da3cb8f5291afa6d221572ef23bbed48b4e Mon Sep 17 00:00:00 2001 From: Boozebeard Date: Fri, 19 Dec 2025 14:24:56 +0100 Subject: [PATCH] Fix for polygroups and masks Previous version was losing its position in the binary when parsing the polypaint data, causing all data that was parsed after polypaint to be lost, including polygroup and mask data. Fixed by checking ahead for the next data type tag after each polypaint block is parsed. Disclaimer: Understanding exactly how to parse and check all this binary data went a bit above my head, so I used AI a lot here to help me. Worth double checking it didn't do something weird. --- gob_import.py | 147 +++++++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/gob_import.py b/gob_import.py index 8b51298..31490e5 100644 --- a/gob_import.py +++ b/gob_import.py @@ -143,7 +143,7 @@ def GoZit(self, pathFile): goz_file.seek(cnt, 1) if utils.prefs().performance_profiling: start_time = utils.profiler(start_time, "____Unpack Mesh Name") - + # Subdivision Levels elif tag == b'\x8a\x13\x00\x00': goz_file.seek(4, 1) @@ -208,7 +208,7 @@ def GoZit(self, pathFile): if utils.prefs().debug_output: print("__ Mask:", tag) break - # Polyroups + # Polygroups elif tag == b'\x41\x9c\x00\x00': if utils.prefs().debug_output: print("__ Polyroups:", tag) @@ -298,85 +298,102 @@ def GoZit(self, pathFile): if utils.prefs().debug_output: print("Import Polypaint: ", utils.prefs().import_polypaint) - goz_file.seek(4, 1) # Always skip the header + goz_file.seek(4, 1) # Always skip the header cnt = unpack('= (3,4,0): - if not me.color_attributes: - me.color_attributes.new(utils.prefs().import_polypaint_name, 'BYTE_COLOR', 'POINT') - - alpha = 1 - for i in range(cnt): - # Avoid error if buffer length is less than 3 - vertex_data = goz_file.read(3) - if len(vertex_data) < 3: - if utils.prefs().debug_output: - print(f"Error: Buffer length less than 3 at index {i} {cnt}: {vertex_data}") - break - colordata = unpack('<3B', vertex_data) # Color - goz_file.seek(1, 1) # Skip Alpha byte - - # Convert color to vector - rgba = [x / 255.0 for x in reversed(colordata)] + [alpha] - - # Check that the index is within the range before assigning - if i < len(me.attributes.active_color.data): - me.attributes.active_color.data[i].color_srgb = rgba - - if utils.prefs().performance_profiling: + bm.to_mesh(me) + bm.free() + me.update(calc_edges=True, calc_edges_loose=True) + else: + if not me.color_attributes: + me.color_attributes.new(utils.prefs().import_polypaint_name, 'BYTE_COLOR', 'POINT') + for i, rgba in enumerate(polypaintData): + if i < len(me.attributes.active_color.data): + me.attributes.active_color.data[i].color_srgb = rgba + + if utils.prefs().performance_profiling: start_time = utils.profiler(start_time, "Polypaint Assign") - else: - # Skip over the polypaint data if not importing - goz_file.seek(cnt * 4, 1) # Skip the polypaint weights + # Not importing polypaint: skip to next tag by scanning remaining bytes + if remaining_bytes is None: + # step-scan + while True: + peek = goz_file.read(4) + if len(peek) < 4: + break + if peek in tag_set: + goz_file.seek(-4, 1) + break + goz_file.seek(-3, 1) + else: + data = goz_file.read(remaining_bytes) + found_at = None + for idx in range(0, len(data)-3, 4): + if data[idx:idx+4] in tag_set: + found_at = idx + break + if found_at is None: + goz_file.seek(pos + len(data), 0) + else: + goz_file.seek(pos + found_at, 0) # Mask elif tag == b'\x32\x75\x00\x00': @@ -726,7 +743,3 @@ def run_import_periodically(): def run_import_manually(): gob_import_cache.clear() bpy.ops.scene.gob_import() #only call operator update is found (executing operatros is slow) - - - -