Jump to content


Regular Member
  • Content Count

  • Joined

  • Last visited

Community Reputation

5 Noble Beginner

Profile Information

  • First Name
  • Last Name
  • C4D Ver
    20.057 Studio

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Hi, in this case you don't need to call GetObject() as the Python code is actually on the object itself. You use that in a tag because "op" is the tag there (quirk of the Python tag in Cinema), so when you call op.GetObject() you're actually getting the object that the tag is on by calling the tag's "GetObject" function. This means all you should need is op[c4d.ID_USERDATA,8] =50 etc.
  2. Well you know you can start out with what you have here, just swap out the null for a python generator, copy and paste your interface over and add the message receiving function to accept your button presses then go from there. You can use it to set the default parameters however you want. Useful things to help you as you go - you can drag & drop in GUI elements to get their ID's directly from the Attributes Manager, however these just show you the main ID's to check then you should then use c4d.DescID and c4d.DescLevel. I've done basically what i've described with the file attached, this allows you to see how it can work. Then you just need to set your defaults the if statements. I haven't checked that the userdata linked correctly in expresso but you should be ale to quickly check and update those ports if they were incorrectly copied across. In general starting scripting isn't that hard, it's just learning the basics of python. there are lots of courses out there for this, but also a decent documentation on plugincafe.com for the cinema API. It helps having tasks that you have in mind you want to do, then you can figure out the right questions to ask and get answers both on plugincafe.com and here. CameraRig_002_pythonized.c4d
  3. Hi. Ok so I think I got the wrong end of the stick there. The def message(id, data): function belongs on a tag or in a python object. It can only receive messages from its own GUI i.e. user data on that actual tag or object. The buttons you have on the null object will instead send the message to the null object so your script will never get it. If you were to swap the null for a python object then you could handle the GUI changes through that. Effectively it would still work as a null object, you'd just return an "Onull" rather than the default "Ocube" that's in there, but also have the message function. Now if that sounds like too much the hack that we used to do for this when scripting was to use a boolean checkbox instead and as soon as it was checked make the change then disable the checkbox. It's not as clean for the UI but it works. It really depends on how important spit and polish is for you with your object.
  4. Hi. To deal with button presses you need to receive the message MSG_DESCRIPTION_COMMAND, this involves creating the Message function which from the top of my head should go something like : def Message(id, msgData): if id == c4d.MSG_DESCRIPTION_COMMAND: # a button was clicked in the GUI so do something here, check the passed id in the msgData if you have more than one command to figure out which was pressed return True Hope that helps.
  5. Your matrix vectors must be orthogonal, they describe the projections in each axis for the points. You can ensure this by applying cross products of the other two vectors e.g. x = z.Cross(y) and so on. In addition the length of each vector should be unit unless you're intending to scale the object, this is achieved through normalization. Bear in mind that Cinema uses the left hand rule for it's matrices, which is to say stick out your left hand and point the thumb up, point the index out and the middle finger across and that's the "positive" directions (as opposed to the right hand rule where the x+ is inverted). Bringing matrices across from elsewhere isn't always easy, they may assume Z is up (3D Max) or use the right handed rule (inverted x vector) etc. Rotation from Euler requires using the same rotation order as the source. If you go this route then you must make sure that you match rotation orders between applications.
  6. Firstly thing - There is no way to directly access and change the value of the dropdown for the render setting within the Batch Renderer with Python AFAIK. Which means that while it's not very efficient your approach is not terrible when dealing with a body of files, don't feel bad about it, if it works then that's more important than if it works efficiently. Now onto ways you could improve your code : For a start I don't see anything in your script accessing the batch renderer to get the file. So that's done first by using the "GetBatchRender" function, e.g. batchRender = c4d.documents.GetBatchRender() count = batchRender.GetElementCount() for i in range(count): fileName = batchRender.GetElement(i) This goes through the whole list, but perhaps you only want to deal with the first (top most, just about to render) document, in which case you wouldn't do the for loop but would just do fileName = batchRender.GetElement(0). Next, you can just load in and save the file more directly than using CallCommand using the c4d.document.LoadDocument(file, flags). myDoc = c4d.documents.LoadDocument(fileName, c4d.SCENEFILTER_PROGRESSALLOWED) if myDoc is None: return At this point you now have an opened document and can see the progress as the file is loaded in. Your next step is to switch out the render data in that document. Just use the code you already have for that, it's fine. You shouldn't need the EventAdd() function calls in there though. The final step is to re-save your document, this time rather than using CallCommand again you can do it directly. With c4d.document.SaveDocument(doc, file, flags, format) result = c4d.documents.SaveDocument(myDoc, fileName, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, c4d.FORMAT_C4DEXPORT) if result is False: return At this point you should be able to start the batch render and be good to go. If you want you can do this programmatically again without having to use CallCommand by accessing the BatchRender object's SetRendering() function i.e. batchRender.SetRendering(c4d.BR_START) should do the job.

About Us

C4D Cafe is the largest Cinema 4D community. We provide facilities for discussion, showcasing and learning our favourite software.
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, watch tutorials directly from our video gallery,  get your own private messenger, post and upload images, manage your profile and much more. If you need to find solution to your problem or otherwise ask for help, C4D Cafe is the right place to be for learning 3D.  :cowboypistol:

  • Create New...