How to export a prim as gltf

Hello,

I would like to export a prim (and all of its children, and references like materials etc.) as a gltf.

Can anyone provide a sample or at least a hint how to do that (with a script)?

In Create itself it is possible to right click a node in stages and select “Export selected”… that will result in an usd that only contains the prim itself and its children… but no materials etc.

When using File->Export, it is possible to export the whole stage including materials and textures as gltf. That comes close to what I want except that it exports the whole stage instead of the selected prim.

What I get so far:

This converts a whole stage to gltf:

import asyncio
import omni.kit.asset_converter as converter

async def convert():
	taskManager = converter.get_instance()
	task = taskManager.create_converter_task('omniverse://127.0.0.1/Users/XcalibuR/test.usd', 'D:/test.gltf')
	success = await task.wait_until_finished()
	print('success')

asyncio.ensure_future(convert())

So far so good… so I have to export my prim and its references to a new usd first…

from omni.kit.widget.stage import export_utils
from pxr import Usd, UsdGeom, Sdf
import omni.usd

stage = omni.usd.get_context().get_stage()

prims = list()

primToExport = stage.GetPrimAtPath('/Root/PlanningArea/ProductConfigurations/IG/PC_5aee69ce_6fa7_4e3c_8838_f4d945b6ae56')

prims.append(primToExport)

for relationshipTargetPath in primToExport.FindAllRelationshipTargetPaths():
	prims.append(stage.GetPrimAtPath(relationshipTargetPath))

export_utils.export('D:/Test.usd', prims)

That produces a usd that contains my prim, all of its children and the referenced material… but the reference between the prims and materials is gone (probably because of the missing parents (all prims are located at the root in the exported usd)…

Thanks for your help

Carl

OK… I’ve found a way…

from omni.kit.widget.stage import export_utils
from pxr import Usd, UsdGeom, Sdf
import omni.usd
import asyncio
import omni.kit.asset_converter as converter
import os

primToExportName = '/Root/PlanningArea/ProductConfigurations/IG/PC_5aee69ce_6fa7_4e3c_8838_f4d945b6ae56'
tempFileName = 'D:/Test12.usd'
outputFileName = 'D:/Test12.gltf'

stage = omni.usd.get_context().get_stage()

prims = list()

primToExport = stage.GetPrimAtPath(primToExportName)
primToExportPath = primToExport.GetPrimPath()

exportedPrimPath = primToExportPath.ReplacePrefix(primToExportPath.GetParentPath(), '/Root')

prims.append(primToExport)

for xxx in primToExport.FindAllRelationshipTargetPaths():
	prims.append(stage.GetPrimAtPath(xxx))

export_utils.export(tempFileName, prims)

exportedStage = Usd.Stage.Open(tempFileName)

exportedPrim = exportedStage.GetPrimAtPath(exportedPrimPath)

def iterateChildren(prim):
	for child in prim.GetChildren():
		materialRealtionship = child.GetRelationship('material:binding')
		
		if materialRealtionship:
			oldTargets = materialRealtionship.GetTargets()
			materialRealtionship.ClearTargets(True)
			for oldTarget in oldTargets:
				materialRealtionship.AddTarget(oldTarget.ReplacePrefix('/Root/Looks', '/Root'))

		iterateChildren(child)

iterateChildren(exportedPrim)
exportedStage.Save()
exportedStage.Unload()

async def convert():
	taskManager = converter.get_instance()
	task = taskManager.create_converter_task(tempFileName, outputFileName)
	success = await task.wait_until_finished()
	os.remove(tempFileName)

asyncio.ensure_future(convert())

But when calling it again I get the folloing error… I think the layer that is created by the exportutil has to be closed… but how?

At what point are you hitting that error? You can try del exportedStage or any other reference to the layer to finish closing it.

How can I delete exportedStage?

The export_util class does only sace the layer it has created… to I think calling export twice should result in the error too

You can use the del keyword like I showed to delete the object.

1 Like