Extract/save textures from materials using python?

Extract/save textures from materials using python?

KristofferHelander
Enthusiast Enthusiast
1,993 Views
8 Replies
Message 1 of 9

Extract/save textures from materials using python?

KristofferHelander
Enthusiast
Enthusiast

In the material editor there is a nifty little feature to Save Texture that allows you to extract an embedded texture file from the .vpb file. But I would like to do this via script instead on all materials in my scene, is that possible? 

 

In the Node Editor I can see the path for the textures but that path is usually a local path that I don't have access to, so I can't copy the texture from there. I've also tried exporting the scene as an .fbx file, but that only extracts some of the texture and that is a problem.

 

So is there a way to extract all the textures (diffuse, normal, specular, etc.) via script? Is this, or will it be, possible with the new material API in VRED 2023 or can it be done in previous versions (e.g. 2021.3) of VRED as well? 

0 Likes
Accepted solutions (1)
1,994 Views
8 Replies
Replies (8)
Message 2 of 9

seiferp
Community Manager
Community Manager

Without looking into it, I´m pretty sure it is possible with the API in 2023. But the "Save texture" in the material does also work for multiple selected materials now, asking for a folder and saving the image name and format comes that is shown in the path. So, not sure how often you must repeat this but selecting all materials and saving the diffuse-, glossy-, roughness- etc. textures for your selection ...the GUI way... is probably faster than writing a script.

0 Likes
Message 3 of 9

KristofferHelander
Enthusiast
Enthusiast

It is far to many materials and textures to do it manually, it has to be done with script.

 

Looking into the documentation for the vrMaterialService in VRED 2023 I can't find any function for saving or extracting textures?

https://help.autodesk.com/view/VREDPRODUCTS/2023/ENU/?guid=VRED_Python_Documentation_Python_API_V2_c... 

 

How is it done?

0 Likes
Message 4 of 9

markus_keller
Autodesk
Autodesk
Accepted solution

Here is a script that writes all texture in the scene to "c:\vred-snapshots":

import os
def saveImage(image, newPath, doNotOverwriteFiles):
    path = image.getAbsolutePath()        
    newFileName = newPath + os.path.basename(path)
    # making sure that existing images are not
    if doNotOverwriteFiles:
        i = 0
        while os.path.exists(newFileName):
            i = i + 1
            newFileName = newPath + str(i) + "_" + os.path.basename(path)    
    # save image
    vrImageService.saveImage(image, newFileName)
def collectImages():
    images = []
    # collect all materials
    mats = vrMaterialService.getAllMaterials()
    handledImages = set()
    for mat in mats:
        # get all materials from texture
        textures = mat.getTextures()
        for texture in textures:
            image = texture.getImage()
            imageId = image.getObjectId()
            # only collect each image once
            if image.isValid() and not imageId in handledImages:
                images.append(image)
                handledImages.add(imageId)
    return images            
# giving the second parameter True or False, to save
doNotOverwriteFiles = True
for image in collectImages():
    saveImage(image, "c:/vred-snapshots/", doNotOverwriteFiles)


Markus Keller
Principal Engineer
Message 5 of 9

markus_keller
Autodesk
Autodesk

Or as a one-liner if you want to save a specific texture (diffuse for example):

mat.getDiffuseTexture().getImage().toQImage().save("e:\\test.png")



Markus Keller
Principal Engineer
Message 6 of 9

KristofferHelander
Enthusiast
Enthusiast
Is this for 2023 as well? I tried it in 2021.3 on a UPlasticMaterial but I get the error message:
"AttributeError: 'vrMaterialPtr' object has no attribute 'getDiffuseTexture'"
Do I need to convert the material node or something? I did it like this:
mat = getSelectedNode().getMaterial()
mat.getDiffuseTexture().getImage().toQImage().save("c:\\temp\\test.png")
0 Likes
Message 7 of 9

seiferp
Community Manager
Community Manager

The script is for the 2023 v2 API

Message 8 of 9

KristofferHelander
Enthusiast
Enthusiast

I just gave this a go and it looks like it is working nicly - thank you! 🙂

0 Likes
Message 9 of 9

yellowcab
Contributor
Contributor

Hello KristofferHelander,

 

how did you make it work? Did you just copy the code into the script editor? Thanks in advance.

0 Likes