Skip to content

Instantly share code, notes, and snippets.

@danzimmerman
Created February 20, 2022 05:21
Show Gist options
  • Save danzimmerman/a4a02d1b99bea010c98d39aa54603ca2 to your computer and use it in GitHub Desktop.
Save danzimmerman/a4a02d1b99bea010c98d39aa54603ca2 to your computer and use it in GitHub Desktop.
meshcat-python Collada loader texture/color hack
class DaeMeshFileSetObject(object):
def __init__(self, dae_file, meshcat_path_string):
"""
Assumes that all images are in the same directory as the .dae file
"""
self.file = pathlib.Path(dae_file).absolute().resolve()
self.path = meshcat_path_string
# -- we don't really need to hold on to these but for debugging it'll be nice to keep them
self.dae_tree = None
self.file_contents = None
self.img_resource_names = None
self.img_resources = {}
def lower(self):
"""
Shallow preparation of the dict that Meshcat expects from a SetObject
to be passed to Visualizer.window.send.
Eventually this needs to make it into my Meshcat fork but I don't want to
figure out the object hierarchy yet.
"""
with self.file.open('r') as daef:
self.file_contents = daef.read()
self.dae_tree = Et.parse(self.file)
# -- parse the image resource filenames out of the .dae file ElementTree --
img_lib_element = self.dae_tree.find('{http://www.collada.org/2005/11/COLLADASchema}library_images')
if img_lib_element:
self.img_resource_names = [e.text for e in img_lib_element.iter() if e.tag.count('init_from')]
else:
self.img_resource_names = []
# -- base64 encode each of the images and make them into a URI that the Three.js ColladaLoader can consume --
for img_name in self.img_resource_names:
img_path = self.imgdir / img_name
if not img_path.is_file():
raise UserWarning(r'DaeMeshFileSetObject.lower() ERROR! Collada image reference {img_path} not found on disk, make sure texture images are in the same directory as .dae file')
with img_path.open('rb') as imf:
imdata = base64.b64encode(imf.read())
imstr = imdata.decode('utf-8')
imuri = f'data:image/png;base64,{imstr}'
self.img_resources[img_name] = imuri
#mat_uuid = str(uuid.uuid1())
# -- pack this all manually into a dictionary of the right format --
objd = {
u'type':u'set_object', #this is a command I guess?
u'path':self.path,
u'object':{
u'metadata':{'version':4.5, u'type':u'Object'},
u'geometries':[],
u'materials': [],
u'object':{
u'uuid':str(uuid.uuid1()),
u'type':u'_meshfile_object',
u'format':u'dae',
u'data':self.file_contents,
#u'material':mat_uuid,
u'resources':self.img_resources
}
}
}
return objd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment