Hi @jhpark!
I don't work for the SDK team, but I believe the script below will do what you want.
Some quick notes about posting:
-
When entering your code into a post on this forum, make sure you hit this button first

It creates code tags in your post. Put your code in between those and then it will format your code automatically.
-
Also, after submitting, hit the button Topic Tools at the bottom right of your post to Ask as Question.

-
When someone has answered your question correctly, click this button at the bottom of their post.

This makes it clear to the moderators when the question has been correctly answered.
Here's the code. Because you were using ID_BASEOBJECT_COLOR
, I was unsure if you wanted the object's display color or the material color (they are two different things), but I wrote this for the sphere's texture tags' material's color. Also, the code is for the spheres' relative position. More work would need to be done to get the animating position track values into global space.
import c4d
from c4d import gui
def GetNextObject(op):
#function for navigating the hierarchy
if op==None: return None
if op.GetDown(): return op.GetDown()
while not op.GetNext() and op.GetUp():
op = op.GetUp()
return op.GetNext()
c4d.EventAdd()
def getPreviewRange(doc,fps):
#returns the active preview range
fps = doc.GetFps()
fromTime = doc.GetLoopMinTime().GetFrame(fps)
toTime = doc.GetLoopMaxTime().GetFrame(fps)+1
return [fromTime,toTime]
def convertVecToRgb(vector):
#converts vector to rgb list
return [vector[0]*255,vector[1]*255,vector[2]*255]
def main(doc):
fps = doc.GetFps()
previewRange = getPreviewRange(doc,fps) #rather than needing to set frames manually, you can simply resize your preview range.
frame_count = previewRange[1]-previewRange[0]
# this section navigates the hierarchy and saves all of the spheres to a list called 'output'
# it's better to do this than to use doc.SearchObject in the case you have multiple spheres with the same name
obj = doc.GetFirstObject()
if obj==None:
gui.MessageDialog('There are no objects in the scene.')
return
output = []
while obj and obj!=None:
if obj.GetType() == c4d.Osphere:
output.append(obj)
obj = GetNextObject(obj)
if len(output) == 0:
gui.MessageDialog('There are no spheres in the scene.')
# loops through spheres in the scene
for sphere in output:
#prints a separating line to the console
print '#' * 80
for f in range(previewRange[0], previewRange[1]):
doc.SetTime(c4d.BaseTime(0, doc[c4d.DOCUMENT_FPS]))
keyTime = c4d.BaseTime(f,fps) #get the current frame
# POSITION
pTracks = sphere.GetCTracks() #get the sphere's animating tracks
pos = [sphere.GetMl().off.x,sphere.GetMl().off.y,sphere.GetMl().off.z] #get the sphere's default relative position
#replace those values with the animating ones.
for t in pTracks:
descid = t.GetDescriptionID() #get the track's id
if descid[0].id == c4d.ID_BASEOBJECT_REL_POSITION: #see if it matches the object's position track
curve = t.GetCurve() #get the track's animation curve
keyvalue = curve.GetValue(keyTime, fps) #get the animation curve's value at the current frame
if descid[1].id == c4d.VECTOR_X:
pos[0] = keyvalue #add to x
elif descid[1].id == c4d.VECTOR_Y:
pos[1] = keyvalue #add to x
elif descid[1].id == c4d.VECTOR_Z:
pos[2] = keyvalue #add to z
# MATERIAL COLOR
tags = sphere.GetTags() #get sphere's tags
matColor = [] #create material color list
for tag in tags: #loop through sphere's tags
if tag.GetType() == c4d.Ttexture: #check if tag is a texture tag
mat = tag.GetMaterial() #if yes, get the tag's material
tracks = mat.GetCTracks() #get the material's animating tracks
for t in tracks:
descid = t.GetDescriptionID() #get the track's id
if descid[0].id == c4d.MATERIAL_COLOR_COLOR: #see if it matches the material color track
curve = t.GetCurve() #get the track's animation curve
keyvalue = curve.GetValue(keyTime, fps) #get the animation curve's value at the current frame
matColor.append(keyvalue*255) #add r,g,b to matColor
if len(tracks) == 0: #in case it's not animating, use general Color
matColor = convertVecToRgb(mat[c4d.MATERIAL_COLOR_COLOR])
# I prefer using string formatting with the placeholder %s for strings, %d for numbers,
# and the % as the replacement operator
print("Name: %s, Frame: %d, Position (x,y,z): %d,%d,%d, Material Color (r,g,b): %d,%d,%d"%(
sphere.GetName(),f,pos[0],pos[1],pos[2],
matColor[0],matColor[1],matColor[2]))
if __name__=='__main__':
# rather than using documents.GetActiveDocument, I found that you can pass a reference to the document using this method
main(doc)
Here's a scene file where the object's display colors and material colors are different. The display colors are visible in the viewport, but you will see the material color if you render.
Spheres.c4d