Skip to content

Instantly share code, notes, and snippets.

@fwilleke80
Last active January 9, 2024 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fwilleke80/394be4f2c54c670c14cb62b55c54cbdf to your computer and use it in GitHub Desktop.
Save fwilleke80/394be4f2c54c670c14cb62b55c54cbdf to your computer and use it in GitHub Desktop.
[C4D] Export objects and tags of a document to a serialised JSON file
"""
Name-US:Export document as JSON
Description-US:Export document to JSON
"""
import c4d
import json
def serialize_data(data):
"""Serialize special data types
"""
theType = type(data)
typeName = theType.__name__
if theType == c4d.Vector:
# c4d.Vector
resultDict = {'x': data.x, 'y': data.y, 'z': data.z}
elif theType == c4d.Matrix:
# c4d.Matrix
resultDict = {'off': serialize_data(data.off), 'v1': serialize_data(
data.v1), 'v2': serialize_data(data.v2), 'v3': serialize_data(data.v3)}
elif theType == c4d.CPolygon:
resultDict = { 'a': data.a, 'b': data.b, 'c': data.c, 'd': data.d, 'isTriangle': data.IsTriangle() }
elif theType == str:
# String
resultDict = {'value': data.encode('utf-8')}
else:
# Any other data type
resultDict = {'value': data}
resultDict['type'] = typeName
return resultDict
def basecontainer_to_dict(bc):
"""Write all data from a BaseContainer to a dictionary
"""
dataDict = {}
for dataId, data in bc:
if type(data) == c4d.BaseContainer:
dataDict[dataId] = basecontainer_to_dict(data)
else:
dataDict[dataId] = serialize_data(data)
resultDict = {
'type': 'BaseContainer',
'id': bc.GetId(),
'values': dataDict
}
return resultDict
def tag_to_dict(tag):
"""Write all data from a tag to a dictionary
"""
if tag is None:
return {}
resultDict = {
'name': tag.GetName(),
'type': tag.GetType(),
'bits': tag.GetAllBits(),
'info': tag.GetInfo(),
'data': basecontainer_to_dict(tag.GetDataInstance())
}
return resultDict
def iterate_tags(firstTag):
"""Iterate tags on an object, starting with firstTag
Return list with data dictionaries for each tag
"""
resultData = []
tag = firstTag
while tag:
resultData.append(tag_to_dict(tag))
tag = tag.GetNext()
return resultData
def serialize_points(pointObject):
points = pointObject.GetAllPoints()
resultList = []
for point in points:
resultList.append(serialize_data(point))
return resultList
def serialize_polygons(polygonObject):
polygons = polygonObject.GetAllPolygons()
resultList = []
for polygon in polygons:
resultList.append(serialize_data(polygon))
return resultList
def object_to_dict(op):
"""Write all data from an object to a dictionary
"""
if op is None:
return {}
resultDict = {
'name': op.GetName(),
'type': op.GetType(),
'ml': serialize_data(op.GetMl()),
'bits': op.GetAllBits(),
'info': op.GetInfo(),
'tags': iterate_tags(op.GetFirstTag()),
'data': basecontainer_to_dict(op.GetDataInstance())
}
# Point Objects
if op.IsInstanceOf(c4d.Opoint):
resultDict['points'] = serialize_points(op)
# Polygon Objects
if op.GetType() == c4d.Opolygon:
resultDict['polygons'] = serialize_polygons(op)
return resultDict
def iterate_object_hierarchy(firstOp):
"""Iterate objects and children, starting with firstOp
Return list with data dictionaries for each object
"""
resultData = []
op = firstOp
while op:
opData = object_to_dict(op)
opData['children'] = iterate_object_hierarchy(op.GetDown())
resultData.append(opData)
op = op.GetNext()
return resultData
def doc_to_dict(doc):
"""Convert a complete BaseDocument to a dictionary
"""
objects = iterate_object_hierarchy(doc.GetFirstObject())
resultDict = {
'objects': objects
}
return resultDict
def main():
resultData = doc_to_dict(doc)
jsonFilename = c4d.storage.SaveDialog(
title='Save JSON at', force_suffix='json', def_file=doc.GetDocumentName() + '.json')
try:
with open(jsonFilename, 'wb') as jsonFile:
jsonFile.write(json.dumps(resultData, indent=True, sort_keys=True))
print('Saved JSON data to ' + jsonFilename)
except:
print('Error saving JSON data to ' + jsonFilename)
if __name__ == '__main__':
main()
@gsmetzer
Copy link

gsmetzer commented Jan 8, 2024

Interesting, How do I use this script? I have tried running it from Cinema but this script generates a blank Json file. I am trying to take some simple animations and polygons and convert them into a Lottie animation via Json. Any help would be appreciated! @fwilleke80

@fwilleke80
Copy link
Author

@gsmetzer Hi,
Hmmm, it should just work. However it is years and years ago that I wrote this. But as long has you have objects in your scene, something should happen when you run it from the C4D script manager.

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