• Execution Delay When Reading Data from JSON file

    Cinema 4D SDK r21 python
    6
    0 Votes
    6 Posts
    839 Views
    M
    I don't have a lot to add here, @zipit almost pointed everything moreover doing proper profiling for hard drive can be a bit tricky to set up for couple of reasons: Another process may randomly use hard drive (e.g Antivirus checking). Cached file optimization made by either the OS, the processor or even the hard drive itself. Cheers, Maxime.
  • Unexpected Margin/Padding on AddCustomGui

    Cinema 4D SDK r21 python
    12
    0 Votes
    12 Posts
    1k Views
    B
    You are right. self.width = c4d.gui.SizePix(w) self.height = c4d.gui.SizePix(h) self.color = color wasn't actually used. Will close this thread now and crawl to my little cave of shame. lol
  • How to create splitted dialog window

    Cinema 4D SDK
    5
    1
    0 Votes
    5 Posts
    705 Views
    mikeudinM
    @m_adam said in How to create splitted dialog window: But in any case, here it's how it works. Thank you very much, Maxime! Great example!
  • 2 Votes
    2 Posts
    863 Views
    r_giganteR
    Hi Ashton, thanks for sharing your code. Best wishes for the incoming new year! Riccardo
  • Disabling a Protection Tag

    Cinema 4D SDK r21 python
    8
    0 Votes
    8 Posts
    1k Views
    ManuelM
    Hello, @blastframe said in Disabling a Protection Tag: tag[c4d.PROTECTION_P_X] = 0 you should use the right type, this is a Boolean. tag[c4d.PROTECTION_P_X] = False you can use those symbols to define the function : c4d.PROTECTION_NONE c4d.PROTECTION_LOCK c4d.PROTECTION_LIMIT tag[c4d.PROTECTION_P] = c4d.PROTECTION_NONE Last point, using SetParameter doesn't change the fact that you need to send a message to the tag. Cheers, Manuel
  • Layers with the same name?

    Cinema 4D SDK r20 python
    10
    0 Votes
    10 Posts
    1k Views
    M
    Since R21 sp1 issue regarding ByteSeq not being able to be printed in the Python Console is resolved. Cheers, Maxime.
  • 0 Votes
    7 Posts
    3k Views
    M
    The issue about PYTHONPATH is now resolved in R21 Sp2. Cheers, Maxime
  • Blend matrices

    Moved Cinema 4D SDK python
    6
    0 Votes
    6 Posts
    1k Views
    r_giganteR
    Thanks a lot Baca and I apologize for the hurried and shallow answer. Looking deeper in the argument the Computer Animation: Algorithms and Techniques reports: "While it should be obvious that interpolating the translation is straigthforward, it is not at all clear how to go about interpolating the rotations. In fact, it is the objective of this discussion to show that interpolation of orientations can be a problem. A property of 3x3 rotation matrix is that the rows and columns are orthonormal. Simple linear interporlation between the nine pairs of numbers that make up the two 3x3 rotation matrices to be interpolated will not produce intermediate 3x3 matrices that are orthonormal and are, therefore, not rigid body rotations. It should be easy to see that interpolating from a rotation of +90 deg about the y-axis to a rotation of -90 degrees about the y-axis results in an intermediate transformation that is nonsense. So direct interpolation of transformation matrices is not acceptable. There are alternatives representation that are more useful than transformation matrices in performing such interpolations: fixed angle, Euler angle, axis angle, quaternions." Considering your answer providing a reasonable solution using quaternions, I've played something similar using fixed angle def MatrixBlendFixedAngle(mxA, mxB, t): # get mxA scale AScale = mxA.GetScale() # get mxA offset AOff = mxA.off # remove from mxA the scale to retrieve rotation mxA.Scale(c4d.Vector(1/AScale.x, 1/AScale.y, 1/AScale.z) ) # retrieve the HPB representation of mxA AHPB = utils.MatrixToHPB(mxA) # get mxB scale BScale = mxB.GetScale() # get mxB offset BOff = mxB.off # remove from mxB the scale to retrieve rotation mxB.Scale(c4d.Vector(1/BScale.x, 1/BScale.y, 1/BScale.z) ) # retrieve the HPB representation of mxB BHPB = utils.MatrixToHPB(mxB) # execute the linear interpolations for offset, scale and HPB COff = (1 - t) * AOff + t * BOff CScale = (1 - t) * AScale + t * BScale CHPB = (1 - t) * AHPB + t * BHPB # calculate mxC from interpolated HPB mxC = utils.HPBToMatrix(CHPB) # add the interpolated scale mxC.Scale(CScale) # add the interpolated offset mxC.off = COff return mxC Finally with regard to your quaternion solution, for those who are interested in, a discussion on how to make use of quaternions is on GameDev. Cheers, R
  • Best way to get Enable status of an object?

    Cinema 4D SDK r20 python
    3
    1
    0 Votes
    3 Posts
    384 Views
    P
    Sorry I was not clear enough. Your answer (polygon object is "enabled" by definition) triggered me and now I understand. Thanks and my best wishes for a great 2020 for you, your family and your Maxon family. -Pim
  • c4dpy.exe and VS Code on Windows?

    Cinema 4D SDK python windows r21
    9
    1 Votes
    9 Posts
    3k Views
    M
    @rossc1 Thanks for the inputs, I will for sure add a note in the documentation regarding this issue. Just as a follow-up from the current status, it is confirmed and while there is a behavior change in our side due to the new licensing mechanism, the issue also comes from Visual Studio Code, reading directly raw string to detect a valid interpreter, and fail if something is not formated as it wants. However, we received the official confirmation from Visual Studio Code that they will not change their implementation, and not support custom interpreters. But we are still on it. Regarding your needs for an IDE, you can use Pycharm, the only pre-requires is to rename c4dpy to python, unfortunately, we can't officially recommend doing such things since newer OS (Catalina) prevent user changing content of an application package but @dskeith explained everything cleary in How to use c4dpy for Cinema4D R20 SP1. Cheers, Maxime.
  • Make Deformer Affect Objects Outside Hierarchy?

    Cinema 4D SDK r21 python
    12
    0 Votes
    12 Posts
    2k 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
    915 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
    395 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
    392 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
    2k 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
    399 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
    743 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.