• Make Deformer Affect Objects Outside Hierarchy?

    Cinema 4D SDK r21 python
    12
    0 Votes
    12 Posts
    3k Views
    B
    @wuzelwazel Yes, I'm referring to the file you uploaded earlier. There is some delay when hitting Undo. You can see it here: https://www.dropbox.com/s/hayep6r4iyowqt5/c4d194_deformer_affect_outside_hierarchy_02.mp4?dl=0 RE: perhaps making sure the objects with the surface deformers are lower down the list In your file, yep they are. That's why I was wondering why there is a lag.
  • Will R22 be Python 3 as Python 2 "dies" in 2020?

    Cinema 4D SDK r21 python
    4
    0 Votes
    4 Posts
    1k Views
    r_giganteR
    Hi @iluxa7k thanks for following up. At the moment, as told in the very first answer, there are no updates I can share about the adoption of Python 3 in C4D. Rest assured that this is still under our PMs' radar. Best, Riccardo
  • Take Viewport Screenshot

    Cinema 4D SDK r21 python
    6
    0 Votes
    6 Posts
    2k Views
    B
    Thank you all for the response. Appreciate a lot. Specially for the sample code provided by @m_magalhaes as this is my code relating to rendering.
  • gui.TreeViewFunctions.InputEvent arguments error

    Cinema 4D SDK python
    3
    1
    0 Votes
    3 Posts
    435 Views
    M
    This bug is now resolved in R21 sp2. Cheers, Maxime
  • Python: Global Variable vs Plugin ID

    Moved General Talk python sdk
    6
    0 Votes
    6 Posts
    2k Views
    M
    Hi while previous answers give some hints I would like to provide more in-depth answers to these questions. First, what is a global variable? In Python, a global variable is a variable that is stored in the dictionary returned by "globals()". The globals() function returns a dictionary that is local to the current Python Scope. Note that a Python scope only lives for a given time and is not persistent. This means it doesn't save its state or current data to a file so if you restart Cinema 4D, it starts with a fresh new Python Scope) but as long as the host object of the Python Scope is alive the data will be stored. So few things to know about Python implementation within Cinema 4D. Each BaseList2D that implements a Python implementation (Python Generator, Python Scripting Tag, Python Xpresso, Field Layer) has its own Python Scope. That means if I have two Python Generator they don't share the same Python Scope. But they both have a distinct one. Now in a case of a plugin, it's a bit tricky, if you use a global variable let's say in an ObjectData. The global variable will be available for all instances (BaseObject) of this ObjectData. This is because a BaseObject is an instance of an ObjectData implementation. And since there is only one implementation (your ObjectData that uses the global variable) they all use the same global variable. Now when you refer to plugin ID, it's a kind of term abuse. A plugin ID is a unique ID (aka a number who is unique into Cinema 4D context). And can be retrieved from https://developers.maxon.net/forum/pid (you must be logged). So a Plugin ID can be used to register a plugin. When you write BaseObject(100000) Cinema 4D will look at the ObjectData that is registered at the ID 100000 and create a BaseObject that will implement this particular ObjectData. But you can also use a PluginId (or aka a Unique ID) to register a data into a BaseContainer. But what is a BaseContainer? BaseDocument, Objects, tag and pretty much everything a user can find in C4D inherit from BaseList2D, and get a BaseContainer. A BaseContainer is a kind of array (or a dictionary in python), where data are stored according to a given ID. This BaseContainer is owned by the host BaseList2D (seems logical but it's an important point). This way Cinema 4D has a generic way of storing and reading data. So Cinema 4D can automate few things such as saving automatically the data stored in this BaseContainer into a File (aka Cinema 4D File) and read them back when loading the Cinema 4D file. So back to our topic, if we assign a particular value to a "Plugin ID/Unique ID" you can assume that nothing within in Cinema 4D will overwrite this particular value. (Third-party developer can access this data however and may erase them, so that's why we recommend using a Unique ID when you store data in a BaseContainer, this way you are sure to not erase other people data and you're is ok). Of course, this works because everyone plays the game if I can tell. Now back to the initial questions. What's the use case of a global variable in Python in Cinema 4D ecosystem? Storing data across multiple frames. (Can also be done with a BaseContainer, but you have to convert to a DataType that BaseContaienr accept, so list, dict are not supported so you have to "bake" which is slow) Data are only alive for the current lifetime of the host and in maximum the Cinema 4D session. What's the use case of data stored in a BaseContainer in Cinema 4D? Storing data across multiple frames. (See the previous point in some case it may be ineffective). Storing persistent data over multiple Cinema 4D sessions (the data will be stored in the host, e.g. the Python Generator Object by itself, so if you open the file in Cinema 4D, the Python Generator will restore the data in the BaseContainer). Exposing data to others (Maybe other Objects want to know the current value stored in a particular Python Generator Object). Finally, BaseContainer should be primarily chosen but as stated in some condition it makes more sense to use a global variable. And here is how to define a global variable within a Python Generator: import c4d # Checks if the test variables exist in the global dict, if not assign a value of 10 global test if 'test' not in globals(): test = 10 def main(): global test print test return c4d.BaseObject(c4d.Ocube) I hope it answers your questions. Additionally please read BaseContainer Manual. Cheers, Maxime.
  • 0 Votes
    3 Posts
    422 Views
    B
    @m_magalhaes Oh gotcha. Thanks for the reminder. Totally forgot they UNDOTYPE_CHANGE have a different placement thant UNDOTYPE_NEW Thanks again. Have a great day ahead!
  • Multiple animation import

    Cinema 4D SDK python r20 r21
    9
    2
    0 Votes
    9 Posts
    3k Views
    S
    @kbar @m_adam Thanks for the help lads, the markers were already added thanks to Kent suggestion in his previous reply. Now the only things left are a little "GlTF-fighting", and some more polishing, packaging and testing before updating the plugin with a - hopefully - nice animation support ! I'll let you know when that's done (probably not before 2020 though ). Cheers, Loïc
  • 0 Votes
    13 Posts
    2k Views
    indexofrefractionI
    ah... ok, now i understand the picture ! thanks, manuel I marked the thread as solved
  • Python Question

    Moved Cinema 4D SDK
    2
    0 Votes
    2 Posts
    454 Views
    M
    Hi @turrican welcome in the plugincafe community. I moved your topic in the correct category and assigned tags, see (How to Post Questions) Please do it for your next topics. Regarding your question, yes it's possible to do it in python. however, I suggest you contact maxon support to report the initial bug regarding the FBX importer. Now you have to keep in mind here we don't code for you but help you to achieve what you want. So the steps in python for doing it are: Loops over each material. Retrieves their name. Create a Bitmap Shader and assign it to the correct channel of the material (normal). To loop over each material, keep in mind that material in Cinema 4D is BaseMaterial which is a child class of GeListNode so to loop over all material use # Retrieve the first material of the current document mat = c4d.documents.GetActiveDocument().GetFirstMaterial() # loop over each material while mat is not None: # Do the things for each mat mat = mat.GetNext() To create a bitmap shader (c4d.Xbitmap) and assign a texture to it find an example in shader_create_bitmap_r13.py. To know the ID of the normal channel, just drop and drop it into the console, see Python Console - Drag and Drop. Cheers, Maxime.
  • Set Use As Render View

    Cinema 4D SDK python
    3
    0 Votes
    3 Posts
    871 Views
    U
    Thank you Manuel, that works perfectly. I can use CallCommand() but I don't want to as it will always call c4d.EventAdd() and as I can't specify which bd to set as the renderview. I tend to not use CallCommand() in a plugin as it is only be able to be called in the main thread (which would be fine in this case) and as it seems to 'simulate' user interaction.
  • HUD on OpenGl previews

    General Talk python
    10
    0 Votes
    10 Posts
    2k Views
    A
    @m_adam Ah OK great will test it and get back to you, Thanks sir.
  • Adding points to a spline

    Cinema 4D SDK python
    3
    0 Votes
    3 Posts
    857 Views
    ManuelM
    hello, without information from your part, i'll consider this thread as solved and change its states Cheers, Manuel
  • 0 Votes
    9 Posts
    1k Views
    B
    @m_adam Thanks for confirmation. Will close this thead now. Looking forward to the documentation
  • Attach XPresso Graph to GUI via Python

    Cinema 4D SDK
    9
    1
    0 Votes
    9 Posts
    2k Views
    DunhouD
    @ashton_fcs_plugindev That is so cool , Is it finish yet? I am new to GeUserArea too , That's a dreamly example to learn GeUserArea.
  • Get CustomGUI Data in python

    Cinema 4D SDK python c++ r20 sdk
    9
    0 Votes
    9 Posts
    2k Views
    N
    Hello Sebastian, I now understand what the difference is, thank you very much! With the customdata_customgui example file I actually made both a GUI and a custom DataType. So I only needed to change my resource file and modifiy my data code a bit! Best Regards, Florian
  • 0 Votes
    9 Posts
    2k Views
    S
    @m_magalhaes Hello, thank you very much for your inspiration. You've been very helpful. There is no need to overwrite TranslateDescID(), only two macros HandleDescGetVector and HandleDescSetVector can realize my idea. Thanks again! Cheers, Sean
  • Trim a bitmap

    Moved Cinema 4D SDK
    5
    1
    0 Votes
    5 Posts
    1k Views
    G
    Thank you, @s_bach I have enough here to figure out what I need to do. Cheers!
  • 0 Votes
    3 Posts
    838 Views
    M
    Hi @orestiskon SendModelingCommand and especially CurrentStateToObject need the object to be actually in the passed document. So you need to create a temporary doc and use it to operates. As bellow: import c4d def currentState(obj) : return c4d.utils.SendModelingCommand(c4d.MCOMMAND_CURRENTSTATETOOBJECT,[obj],c4d.MODELINGCOMMANDMODE_ALL,c4d.BaseContainer(),obj.GetDocument())[0] def main(): # Retrieve the python generator obj = op.GetDown() if obj is None: return objClone = obj.GetClone() if objClone is None: raise RuntimeError("Failed to clone the object") # Make the children Python Generator disapear obj.Touch() # Creates a temporary document that will be used to evaluate the cache of the object tempDoc = c4d.documents.BaseDocument() if tempDoc is None: raise RuntimeError("Failed to create a temporary doc") # Inserts the child python generator that exists only in memory into our tempo doc tempDoc.InsertObject(objClone) returnedObj = currentState(objClone) return currentState(objClone) Cheers, Maxime.
  • UserData Insert New Data

    Moved Cinema 4D SDK
    4
    1
    0 Votes
    4 Posts
    731 Views
    G
    Hey Guys! I think I figured it out! Will resoond if there's any questions! Cheers! MattG
  • Python Generator associated with User Data?

    Moved Cinema 4D SDK python
    4
    0 Votes
    4 Posts
    1k Views
    M
    Thanks for the great suggestions! I just discovered I can also use "File | Save Object Preset" and "File | Load Object Preset" in the Attribute Manager.