[SU3] Beta 1.5.19 SDK 1.4.4 Blender exporter 4.3.4 - Blender 4.2 - exporting textures does not work

Version: *1.5.19 SDK 1.4.4 exporter 4.3.4 with Blender 4.2

Frequency: Consistently*

Severity: *High
(Low - quality of life, workflow optimization, rare enough to not impact production, etc…
High - critical but workarounds are available, important feature not working as expected, frequent enough to impact production
Blocker - prevents from working on the project, prevents from releasing the product)

Marketplace package name: if applicable

Context: What package? When editing or mounted from Community? In main menu or in flight? etc…

Similar MSFS 2020 issue: insert url here if applicable

Bug description:

If you uncheck Keep Originals and make the texture folder ../texture The exporter in Blender 4.2 will not export the textures to the folder.

Blender 4.2 works a bit different than 3.6. This was reported to Khronos by Yasmine a while back. It all works fine in 3.6

Is your proposed workflow to manually copy the textures and keep_originals checked?

Repro steps:

Attachments:
WASMSimpleAircraft_2024_01.zip

Private attachments: Send a PM to @PrivateContent with the link to this topic and the link to download your content

The example zip is a blend file with the texture images packed.

Make sure you unpack and also make the textures Absolute. Usually unpacking makes the texture go into a textures folder (with an s). However you still need to make these texture images absolute.

See File - the External Data then - Make Paths Absolute.

This is not the ../texture setting in the “keep originals” uncheck textbox

Hello,

Exporting them without unpacking textures does not work neither ? I just tried to do so with your scene and i have the textures exported.

When you unpack them you’ll get the “textures” folder added by Blender and the “texture” folder added with your exported textures.

Correct - packed textures does not work. I gave you a zip of a blend file with textures packed. - So unpack the textures into a “textures” folder - then set the texture paths to Absolute.

File - External Data - Make Paths Absolute.

Then do an export. - result no textures in the PackagesSources / …/ texture folder.

Here is my fix - it is a Kludge code fix - but it works for me.

    # region Textures
    def export_gltf_textures(self, context, gltf_path, texture_dir):
        if not os.path.exists(gltf_path):
            return

        gltf_dir_path = os.path.dirname(gltf_path)

        #print("export_gltf_textures - texture_dir before abs", texture_dir, gltf_path, gltf_dir_path)
        if not os.path.isabs(texture_dir):
            texture_dir = os.path.join(gltf_dir_path, texture_dir)
            texture_dir = os.path.abspath(texture_dir)

        #print("export_gltf_textures - texture_dir abs", texture_dir)
        if not os.path.exists(texture_dir):
            try:
                os.mkdir(texture_dir)
            except OSError:
                self.report({'ERROR'}, f"[TEXTURE] Folder {texture_dir} could not be created")
                return

        json_file_object = None
        try:
            with open(gltf_path, 'r', encoding="utf-8") as file:
                json_file_object = json.load(file)
        except IOError:
            self.report({'ERROR'}, f"[TEXTURE] File '{gltf_path}' could not be opened. File access denied")
            self.report({'ERROR'}, "[TEXTURE] Textures will not be written")
            return

        if json_file_object is None:
            return

        gltf_images = json_file_object.get("images")
        if gltf_images is None:
            return

        # make a file hash for 4.2 - ronh
        image_dict = {}
        for im in bpy.data.images:
           #print("export_gltf_textures - image", im, im.name, im.filepath)
           if im.name != "Render Result":
               image_dict[im.name] = im.filepath.replace('/', '\\')
        for gltf_image in gltf_images:
            # uri image path in Blender 4.2 is not same as Blender 3.6 - does not use relative path added - ronh
            image_path = gltf_image.get("uri")
            #print("export_gltf_textures - original image path found", gltf_image, image_path, image_dict[image_path])
            if image_path is None:
                print("export_gltf_textures - no image path found", gltf_image)
                continue

            # added the 4.2 check - ronh
            if bpy.app.version < (4, 2, 0):
                image_path = os.path.join(gltf_dir_path, image_path)
                image_path = image_path.replace('/', '\\')
            else:
                #image_path = os.path.join(texture_dir, image_path)
                # because there is no proper uri in 4.2+ - build texture_dir path
                texture_path = os.path.join(gltf_dir_path, texture_dir)
                image_path = os.path.join(texture_path, image_dict[image_path])
            #print("export_gltf_textures - image_path before", texture_path, image_path)
            image_path = os.path.abspath(image_path)
            #print("export_gltf_textures - image_path after", image_path)

            # Check if there is a whitespace and replace it in path
            if '%20' in image_path:
                image_path = image_path.replace('%20', ' ')

            #print("export_gltf_textures \n", gltf_dir_path, texture_dir, image_path)
            # commented out - ronh
            #if not os.path.exists(image_path):
            #    print(f"[TEXTURE] File '{image_path}' do not exists")
            #    continue

            image_name = os.path.basename(image_path)

            new_image_path = os.path.join(texture_dir, image_name)
            new_image_path = os.path.abspath(new_image_path)
            #print("export_gltf_textures - new image path", image_path, new_image_path)

            # Change texture path in gltf
            if len(os.path.commonprefix([new_image_path, gltf_path])) != 0:
                gltf_image['uri'] = os.path.relpath(path=new_image_path, start=gltf_dir_path)

            # Copy image if the image not already exists in the folder
            if _samefile(image_path, new_image_path):
                print("export_gltf_textures - same file", image_path, new_image_path)
                continue

            if p4.us_p4():
                p4.p4_edit(new_image_path)

            copyfile(image_path, new_image_path)
            print(f"[TEXTURE][{image_name}] Texture copied from '{image_path}' to '{new_image_path}'")
            # to remove misplaced png files.  I don't know why - kludge code - ronh
            bad_image_path = os.path.join(gltf_dir_path, image_name)
            bad_image_path = os.path.abspath(bad_image_path)
            try:
                os.remove(bad_image_path)
            except:
                pass

        # Serializing json
        json_object = json.dumps(json_file_object, indent=4)

        # Write in file
        try:
            file = open(gltf_path, 'w+', encoding="utf-8")
            if file:
                file.write(json_object)
            file.close()
            #print("export_gltf_textures - json write")
        except IOError:
            self.report({'ERROR'}, f"[TEXTURE] File '{gltf_path}' could not be written. File access denied")
            return

        return

EDIT: my testing has resulted in the requirement that - “ALL Textures in the blend file MUST be set to absolute” 4.2 has really messed up path joins etc.

One more thing.

My kludge code seems to make two copies of the image textures. One in the correct texture folder and also in the model folder (however there are no xml files generated there).

I cannot seem to figure out why. I assume it’s because of the subprocess you have set up, but unchecking background process does nothing.

So I have an os.remove at the bottom of the function to cleanup the image files in the model folder.

To fix the export of packed image you just need to change this line in msfs_multi_expot.py:

export_keep_originals=(settings.export_keep_originals if settings.enable_msfs_extension else settings.export_keep_originals),

As for the unpacked textures i can’t seem to get the same result as you. I’ll try to repro your issue.

I’m om Blender 4.2.12 - Blender and Khronos make breaking changes to things.

Are you using our original MSFS2024 exporter ? i’m on Blender 4.2.12 too ^^

Yes my bug reports are with your exporter. I have updated mine to work like I require. Mine works, yours does not.

I see you tested by exporting to an export folder next to or under the blend source file. I suggest you test like a developer an make a packagesources folder with common and model folder.

1 Like

Hello,

Do you still repro the issue with the latest SDK ?

Thank You !

The issue of texture not exporting or being duplicated into the model folder is fixed.

1 Like