Skip to content

Instantly share code, notes, and snippets.

@joncardasis
Last active September 15, 2025 05:03
Show Gist options
  • Select an option

  • Save joncardasis/e815ec69f81ed767389aa7a878f3deb6 to your computer and use it in GitHub Desktop.

Select an option

Save joncardasis/e815ec69f81ed767389aa7a878f3deb6 to your computer and use it in GitHub Desktop.

Revisions

  1. joncardasis revised this gist Jun 12, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions ColladaAnimationForXcode.py
    Original file line number Diff line number Diff line change
    @@ -50,9 +50,9 @@ def xml_is_collada(xml_string):
    xml_string = re.sub('(?:<{tag}>)([\s\S]+?)(?:</{tag}>)'.format(tag=tag), '', xml_string)

    # Combine animation keys into single key:
    # 1. Remove all <animation id=...> tags.
    # 1. Remove all <animation> tags.
    # 2. Add leading and trailing <library_animation> tags with single <animation> tag between.
    xml_string = re.sub(r'\s*(<animation id=[^>]*>)\s*', '\n', xml_string)
    xml_string = re.sub(r'\s*(<animation[^>]*>)\s*', '\n', xml_string)
    xml_string = re.sub(r'\s*(<\/animation\s*>.*)\s*', '', xml_string)

    xml_string = re.sub(r'\s*(<library_animations>)\s*', '<library_animations>\n<animation>\n', xml_string)
  2. joncardasis revised this gist Jun 12, 2018. 1 changed file with 10 additions and 4 deletions.
    14 changes: 10 additions & 4 deletions ColladaAnimationForXcode.py
    Original file line number Diff line number Diff line change
    @@ -5,10 +5,10 @@
    # only leaving animations and bone structures behind.
    # Combines multiple animation sequences into a single animation
    # sequence for Xcode to use.
    #
    import sys
    import os
    import re
    import subprocess

    def print_usage(app_name):
    print 'Usage:'
    @@ -49,8 +49,14 @@ def xml_is_collada(xml_string):
    for tag in DAE_TAGS_TO_STRIP:
    xml_string = re.sub('(?:<{tag}>)([\s\S]+?)(?:</{tag}>)'.format(tag=tag), '', xml_string)

    # Combine animation keys into single key
    xml_string = re.sub("1,/<animation id.*>/s/<animation id.*>/<animation>/;/<animation id.*>/d;/<\/animation>/d;/<\/library_animations>/s/<\/library_animations>/<\/animation>/;/<\/animation>/a\'$'\n<\/library_animations>", '', xml_string)
    # Combine animation keys into single key:
    # 1. Remove all <animation id=...> tags.
    # 2. Add leading and trailing <library_animation> tags with single <animation> tag between.
    xml_string = re.sub(r'\s*(<animation id=[^>]*>)\s*', '\n', xml_string)
    xml_string = re.sub(r'\s*(<\/animation\s*>.*)\s*', '', xml_string)

    xml_string = re.sub(r'\s*(<library_animations>)\s*', '<library_animations>\n<animation>\n', xml_string)
    xml_string = re.sub(r'\s*(<\/library_animations>)\s*', '\n</animation>\n</library_animations>', xml_string)

    # Rename original and dump xml to previous file location
    os.rename(file_path, renamed_dae_path)
    @@ -63,4 +69,4 @@ def xml_is_collada(xml_string):

    if failed_file_conversions > 0:
    print '\nFailed {} conversion(s).'.format(failed_file_conversions)
    sys.exit(1)
    sys.exit(1)
  3. joncardasis created this gist Jun 12, 2018.
    66 changes: 66 additions & 0 deletions ColladaAnimationForXcode.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    #!/usr/local/bin/python
    # Jonathan Cardasis, 2018
    #
    # Cleans up a collada `dae` file removing all unnessasary data
    # only leaving animations and bone structures behind.
    # Combines multiple animation sequences into a single animation
    # sequence for Xcode to use.
    #
    import sys
    import os
    import re

    def print_usage(app_name):
    print 'Usage:'
    print ' {} [path(s) to collada file(s)...]'.format(app_name)
    print ''

    def xml_is_collada(xml_string):
    return bool(re.search('(<COLLADA).*(>)', xml_string))

    ################
    ## MAIN ##
    ################
    DAE_TAGS_TO_STRIP = ['library_geometries', 'library_materials', 'library_images']

    if len(sys.argv) < 2:
    app_name = os.path.basename(sys.argv[0])
    print_usage(app_name)
    sys.exit(1)

    print 'Stripping collada files of non-animation essential features...'
    failed_file_conversions = 0

    for file_path in sys.argv[1:]:
    try:
    print 'Stripping {} ...'.format(file_path)
    dae_filename = os.path.basename(file_path)
    renamed_dae_path = file_path + '.old'

    dae = open(file_path, 'r')
    xml_string = dae.read().strip()
    dae.close()

    # Ensure is a collada file
    if not xml_is_collada(xml_string):
    raise Exception('Not a proper Collada file.')

    # Strip tags
    for tag in DAE_TAGS_TO_STRIP:
    xml_string = re.sub('(?:<{tag}>)([\s\S]+?)(?:</{tag}>)'.format(tag=tag), '', xml_string)

    # Combine animation keys into single key
    xml_string = re.sub("1,/<animation id.*>/s/<animation id.*>/<animation>/;/<animation id.*>/d;/<\/animation>/d;/<\/library_animations>/s/<\/library_animations>/<\/animation>/;/<\/animation>/a\'$'\n<\/library_animations>", '', xml_string)

    # Rename original and dump xml to previous file location
    os.rename(file_path, renamed_dae_path)
    with open(file_path, 'w') as new_dae:
    new_dae.write(xml_string)
    print 'Finished processing {}. Old file can be found at {}.\n'.format(file_path, renamed_dae_path)
    except Exception as e:
    print '[!] Failed to correctly parse {}: {}'.format(file_path, e)
    failed_file_conversions += 1

    if failed_file_conversions > 0:
    print '\nFailed {} conversion(s).'.format(failed_file_conversions)
    sys.exit(1)