Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Thank you, Ferdinand.
It looks like the only part I missed in my code was that extra line
doc.ExecutePasses(bt=None, animation=True, expressions=True, caches=True, flags=c4d.BUILDFLAGS_NONE)
After updating the code on my side - everything seems to be working fine. Thank you again. Best regards, Tomasz
Hi, I spent some time yesterday trying to develop a Python script, which travels through takes, grabbing camera position (which is changed every time by aligning to spline tag), creating a null object and copying camera Matrix to null. The part I'm struggling with is grabbing the camera position. I either got the original camera position, before it's been modified by aligning to spline property or value 0. Below is my code and also attached scene, which I've been using for tests. Am I missing something obvious?
import c4d from c4d import documents list_of_takes = [] parent_name = "360_cams" def GetCategory(doc): takeData = doc.GetTakeData() if takeData is None: return mainTake = takeData.GetMainTake() take = mainTake.GetDown() while take is not None: list_of_takes.append((take)) take = take.GetNext() def CreateParentObject4360CamExport(doc): cam_export_parent = doc.SearchObject(parent_name) if cam_export_parent is not None: cam_export_parent.Remove() c4d.CallCommand(5140) # Null cam_export_parent = doc.SearchObject("Null"); c4d.CallCommand(1019940) # Reset PSR if cam_export_parent != None: cam_export_parent.SetName(parent_name) return cam_export_parent def CreateCopyOfTheCamera(currentCam,currentTake, doc,take_data): c4d.CallCommand(5103) # Camera camTemp = doc.SearchObject("Camera") c4d.CallCommand(1019940) # Reset PSR if camTemp != None: camTemp.SetName(currentTake.GetName()) print("current cam : "+ currentCam.GetName() + " and position " + str(currentCam.GetMg())) camTemp.SetMg(currentCam.GetMg()) c4d.EventAdd() return camTemp # Main function def main(): doc = documents.GetActiveDocument() takeData = doc.GetTakeData() if takeData is None: raise RuntimeError("No take data in the document.") cam_export_parent = CreateParentObject4360CamExport(doc) main_take = takeData.GetMainTake() GetCategory(doc) for child_take in list_of_takes: takeLoaded = takeData.SetCurrentTake(child_take) if takeLoaded == True: currentCam = child_take.GetCamera(takeData) cam2NullClone = CreateCopyOfTheCamera(currentCam,child_take,doc,takeData) cam2NullClone.InsertUnder(cam_export_parent) c4d.EventAdd() # Execute main() if __name__=='__main__': c4d.CallCommand(13957) # Clear Console main()
Link to c4d file
Hi Manual, This is exactly what I needed. Thank you very much. Best regards, Tomasz
Hi Manuel, I've tested your solution and it works like a charm Thank you. As a next step, I wanted to grab node transforms from takes. I tried with c4d.DescID(c4d.ID_BASEOBJECT_REL_POSITION), but I'm not able to get any data. Below is your code with added two extra lines to get the node position. I also attached a screenshot with details from one of the takes.
Can you please help with the problem?
import c4d from c4d import gui # as Takes are BaseList2D, we can use GetNext, GetPred, GetUp, GetDown def GetNextTake(op): if op == None: return None if op.GetDown(): return op.GetDown() while not op.GetNext() and op.GetUp(): op = op.GetUp() return op.GetNext() def main(): takeData = doc.GetTakeData() visibilityDescID = c4d.DescID ( c4d.ID_BASEOBJECT_VISIBILITY_EDITOR) nodePositionAbs = c4d.DescID ( c4d.ID_BASEOBJECT_REL_POSITION) currentTake = takeData.GetMainTake() while currentTake: overrides = currentTake.GetOverrides() for override in overrides: descIDs = override.GetAllOverrideDescID() if visibilityDescID in descIDs: print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "value", override[visibilityDescID]) if nodePositionAbs in descIDs: print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "position", override[nodePositionAbs]) currentTake = GetNextTake(currentTake) # Execute main() if __name__=='__main__': main()
Hi Manuel, Thank you. I'll test it and come back to you if I have any questions. Best regards, Tomasz
Hi Manuel, What I really need is a code snippet to travel thru all takes, list all nodes per take with visibility changed, as per the screenshot below. https://i.imgur.com/qedKv2K.png I'd like to also know if there is a way to find what else has been changed per object (like coordinates) I already got a code to rebuild takes, from a text file, when the updated mesh is imported and replacing the current mesh on the scene, so that's the only part which I need to make the solution work Best regards, Tomasz
Hi, I'm looking for a way to export info about objects, disabled for rendering, from take system, and use it later. I got a scene with hundreds of different viewpoints, each in separate take. If there are objects obstructing camera view, for that viewpoint, they I hide them for each take. That works great, and I'm big fan of Take System. The issue starts as soon as I want to bring updated mesh into my scene. As soon as the old mesh is deleted, and new mesh imported to the scene - all my references to previously hidden objects are gone (even the new mesh got identical hierarchy and names). As I understand Take Systems uses pointer to the scene node, rather than name of the object, which of course make sense. To avoid hours of extra work every time when I bring updated mesh to c4d, to go thru all viewpoint and re-hide previously hidden objects, I'm looking for a solution to save info about hidden objects for each take, and then with the new mesh, just re-generate it in Python. I checked all take examples on GitHub, as well as this forum, but was unable to find anything helpful for the task.
Can you please help me with this problem? Best regards, Tomasz
Hi Ferdinand,
Thank you for the explanation. Real shame the Asset API has not been exposed to Python yet. I'll wait till it's done and fully documented - let's hope it will be soon.
Best regards, Tomasz
Hi, As a part of an automated system, I load required materials and assets, when preparing the first version of a scene, from the Content Browser (Cinema 4D R23), using simple Python code (below, for materials)
def LoadMaterial(location, name): doc = c4d.documents.GetActiveDocument() location = "preset://" + location + "/" + name status = c4d.documents.MergeDocument(doc, location, c4d.SCENEFILTER_MATERIALS) return status
As I understand the Content Browser have been replaced by Asset Browser, which looks much more powerful and I can't wait to start using it I can import all the assets from lib4d into R25 and access them manually, but I really need is the ability to load the assets from a code, as I do in r23. What's the best way of doing that? Can you provide me with a code snippet?
I basically want to have the same ability as in R23, wherein r25 I can pass DB name (or full path), together with object/mat name, and be able to download it to the scene. Also - is there a way to list all versions of an object or materials, and then choose one to download?
Thank you @zipit I adopted your solution into our code and it works exactly as expected. Thank you for your help. Best regards, Tomasz