Skip to content

Instantly share code, notes, and snippets.

@NiklasRosenstein
Last active June 22, 2019 16:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NiklasRosenstein/05a8fbeeef3c8e55731ce7912ba03a60 to your computer and use it in GitHub Desktop.
Save NiklasRosenstein/05a8fbeeef3c8e55731ce7912ba03a60 to your computer and use it in GitHub Desktop.
Extract all files of the Cinema 4D SDK into a separate directory.
# Extract the Cinema 4D SDK from a Cinema 4D installation.
# Copyright (C) 2016 Niklas Rosenstein
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__author__ = 'Niklas Rosenstein <rosensteinniklas@gmail.com>'
__version__ = '1.0.0'
import argparse
import glob2
import os
import re
import shutil
parser = argparse.ArgumentParser()
add_arg = parser.add_argument
add_arg('path', help = 'Path to the Cinema 4D installation.')
add_arg('outdir', help = 'The output directory to put the gathered files into.')
add_arg('-C', '--collect-resources', action = 'store_true', help = 'Collect all header and resource files into the SDK main directory.')
add_arg('-V', '--version', type = int, help = 'The Cinema 4D version if it can not be determined from the installation path.')
old_api_maindir = 'resource/_api'
old_api_sources = [
'resource/_api/**/*',
'resource/_api_lib/**/*',
]
old_api_resources = [
'modules/*/res/description/*.h',
'modules/*/res/description/*.res',
'modules/*/*/res/description/*.h',
'modules/*/*/res/description/*.res',
'resource/res/description/*.h',
'resource/res/description/*.res',
'resource/modules/*/res/description/*.h',
'resource/modules/*/res/description/*.res'
]
new_api_maindir = 'frameworks/cinema.framework/source'
new_api_sources = [
'frameworks/**/*'
]
new_api_resources = [
'resource/modules/*/description/*.h',
'resource/modules/*/description/*.res'
]
def figure_c4d_version_from_path(path):
base = os.path.basename(path.rstrip('/').rstrip('\\'))
match = re.match('(\d\d\.\d\d\d)_', base)
if match:
parts = match.group(1).split('.')
return int(parts[0]) * 1000 + int(parts[1])
match = re.match('cinema.*R(\d\d)(\.\d\d\d)?', base, re.I)
if match:
parts = match.group(1), match.group(2).lstrip('.') or '000'
return int(parts[0]) * 1000 + int(parts[1])
raise ValueError('unable to detect Cinema 4D version from path: "{}"'
.format(path))
def makedirs(path):
if not os.path.isdir(path):
os.makedirs(path)
def multiglob(patterns, parent = None):
result = []
for pattern in patterns:
if parent: pattern = os.path.join(parent, pattern)
result += glob2.glob(os.path.normpath(pattern))
return result
def main():
args = parser.parse_args()
if not args.version:
args.version = figure_c4d_version_from_path(args.path)
elif args.version < 100:
args.version = args.version * 1000
if args.version < 16000:
maindir = old_api_maindir
sources = old_api_sources
resources = old_api_resources
else:
maindir = new_api_maindir
sources = new_api_sources
resources = new_api_resources
sources = sorted(multiglob(sources, args.path))
resources = sorted(multiglob(resources, args.path))
# Copy the header and source files of the SDK into the output directory
# with the same folder structure.
for fn_in in filter(os.path.isfile, sources):
arcname = os.path.relpath(fn_in, args.path)
print('Copying', arcname)
fn_out = os.path.join(args.outdir, arcname)
makedirs(os.path.dirname(fn_out))
shutil.copyfile(fn_in, fn_out)
# Copy the resource files, either pasting them into the SDK main directory
# where also the header files are placed or in the same folder structure,
# depending on the settings.
for fn_in in filter(os.path.isfile, resources):
arcname = os.path.relpath(fn_in, args.path)
print('Copying', arcname)
if args.collect_resources:
arcname = os.path.join(maindir, os.path.basename(fn_in))
fn_out = os.path.join(args.outdir, arcname)
makedirs(os.path.dirname(fn_out))
shutil.copyfile(fn_in, fn_out)
# Create a file that denotes the version of the SDK.
filename = os.path.join(args.outdir, 'c4d-sdk-{}.txt'.format(args.version))
with open(filename, 'w') as fp:
print('Generated with extract-c4d-sdk.py', file = fp)
if __name__ == '__main__':
main()
@bentraje
Copy link

Hi Niklas,
Thank you for sharing the code. Although, I am having a problem when I run the code:
File "scriptmanager", line 129 print('Generated with extract-c4d-sdk.py', file = fp) ^ SyntaxError: invalid syntax

Is there a way around this?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment