• Unable to Retrieve the Input Port of Value Node

    2023 python
    3
    1
    0 Votes
    3 Posts
    486 Views
    B
    @manuel said in Unable to Retrieve the Input Port of Value Node: port = node.GetInputs().FindChild("in") Ah I gotcha. I always forget about displaying IDs in hte preferences since I'm hopping between old and newest versions of C4D. My bad. Anyhow, works as expected.
  • 0 Votes
    6 Posts
    755 Views
    ferdinandF
    Hey @thomasb, Thank you for the clarification. Yeah, this setup requires you modifying the cache. So, the slow performance version with disabling the optimization is the best you can do when approaching things in such brutish manner. FYI: I do not have much time this week, so this is all the help you will get this week from me, but I am happy to help you next week if you still need help then. Things you can do: Turning off the optimization will calculate the cache every time Cinema 4D asks for it. Depending on how your blinking works, you might not have to calculate the cache every frame. Just determine when a new cache is needed and when not, as demonstrated in my first posting. When in 99% of the cases 99% of your old invalid cache is still good, nothing prevents you from either caching expensive to compute parts yourself or modifying the existing cache and return that as the new one. Changing a selection state is such an example of where 99.9% of the expensive work is still valid. It would be quite easy to do, when selection tags could reach into caches, but they cannot. So, you cannot have a selection tag on a generator (in Python) which indexes elements of the cache. But you can have a selection tag inside the cache which is referenced by for example a material on the generator holding the cache. With this knowledge, you can: Write a solution following (2.) where everything happens in the object, but in most cases, you just modify an existing cache instead of creating a new one. Do the same, but here you use a tag to modify the cache. This is a little bit dicey, as you should not mess with caches. But in this specific form, where we only change the selection state of a selection tag inside the cache, it should be okay. All other external cache modifications are off limits and can lead to crashes when you do not know what you are doing. In a nicer variant, you would implement the tag as a TagData plugin, but I provided a simple Python programming tag version below. The shader solution is not viable in Python; it will be too slow. You will also need quite some math knowledge and reverse engineering skills, as you would have to sort of reimplement texture mapping. PS: In your more complex setup, this could mean that you just change the materials on things. Although consolidating things inside caches is always advantageous. The more generators your cache contains, the more expensive it will be to evaluate the cache of your object. When possible, it is always better to return a single polygon object as your cache result, or at least a tree which contains only null objects and polygon objects, and no generator objects as the Sphere object, instance-objects, cloners, etc., i.e., things which must be cached themselves. When the cache for an object is being built, all that stuff is converted to polygons anyway. But when you return one hundred instance objects which reference a sphere generator each, cinema will have to build 102 caches in total: one for your object, one for the sphere object, and one hundred for the instance objects. When you just return one polygon object which contains all the geometry, Cinema 4D must build only one cache. In Python this fact is a little bit mitigated by the slowness of Python, and it can be advantageous to push things to C++, but your cache is too complicated IMHO. Just construct your LED once, then build the cache for it, copy the cache thirty-five times, modify the position and material of each copy, and return these thirty-five copies under a null object as your object cache. Cheers, Ferdinand File: led.c4d Result:[image: 1674038759398-led_ani.gif] Python Generator object: import c4d op: c4d.BaseObject # The Python Generator object containing this code. def main() -> c4d.BaseObject: """Returns a clone of the polygon object linked in its first user data field. """ source: c4d.PolygonObject = op[c4d.ID_USERDATA, 1] if not isinstance(source, c4d.PolygonObject): return c4d.BaseObject(c4d.Onull) clone: c4d.PolygonObject = source.GetClone(c4d.COPYFLAGS_NO_HIERARCHY | c4d.COPYFLAGS_NO_BITS) clone.SetMg(c4d.Matrix()) return clone Python Programming tag: import c4d doc: c4d.documents.BaseDocument # The document evaluating this tag. op: c4d.BaseTag # They Python Programming tag containing this code. def main(): """Reaches into the cache of its host object and modifies it. """ # Get the host object, its cache, and find the polygon selection tag on it. obj: c4d.BaseObject = op.GetMain() if not isinstance(obj, c4d.BaseObject): return cache: c4d.BaseObject = obj.GetCache() if not isinstance(cache, c4d.PolygonObject): return tag: c4d.SelectionTag = cache.GetTag(c4d.Tpolygonselection) if not isinstance(tag, c4d.SelectionTag): return # Get the current document frame and the selection of the tag and flush it. In practice you could # also make this parameter driven, but for expressions, tags, it is also fine to make things # automatic as such. frame: int = doc.GetTime().GetFrame(doc.GetFps()) bs: c4d.BaseSelect = tag.GetBaseSelect() bs.DeselectAll() # Define the indices of 100 cap polygons, and pick the polygon which matches the current time. states: list[int] = [n for n in range(4, 599, 6)] i: int = states[frame % 100] # Set the new selected element. bs.Select(i)
  • Make Description Parameter Uneditable

    r23 2023 python windows
    3
    1
    0 Votes
    3 Posts
    554 Views
    ThomasBT
    @ferdinand As always thank you very much Ferdinand, it works as expected
  • A few items that should get fixed on the Python side

    2023 python
    6
    0 Votes
    6 Posts
    1k Views
    M
    @ferdinand said in A few items that should get fixed on the Python side: Hey @mikegold10, ..., the word "of" does not in any way indicate ownership, [...] It does, of is a possessive preposition, in is a relative preposition, specifically one that denotes a place. See here for an overview of the subject. I would not even challenge the fact that for you and your peers of might sound more natural (or maybe even all native speakers as you claim). But language in general, and especially things like prepositions, pronouns, and flexions, is subject to language change which is often highly regional, so what people consider correct can vary regionally. As indicated in my first answer, prepositions are quite interchangeable, and if the text would have said of instead of in, I would not waste any time on changing that. But in the same notion, I cannot change the preposition on what you subjectively consider better. The grammatical situation from a Standard English point of view seems obvious here and personal preference cannot be grounds for a change. I am more than happy to change the preposition when you can demonstrate with a respectable English style guide like Oxford English that it would be more common to use here of. But that seems unlikely to me. Cheers, Ferdinand As additional supportive evidence for my proposed change, I am providing a link to a respected source for the definitions of American English words, including many sample phrases that provide context for the often huge set of alternative definitions that are provided for commonly used words like "of" (and "in"): Meriam-Webster Dictionary: of - Definition / preposition Specifically, under the definitions of the word "of," when used as a preposition (i.e., Section 1 of 3 on the page, as linked above), please examine the following alternative definitions and examples of proper English usage that I believe are of relevance to my proposed change to the original Python comment: a, c, and e a and b b Here is a copy of the original comment to provide context: The index of the first and last selected elements in the given segment. ..., and the revised version that replaces the preposition in with of:: The index of the first and last selected elements of the given segment. Of course the decision is yours to make. I am simply trying to "open your mind" to, as well as provide objective evidence for, an alternative phrasing which I perceive to be a better fit for the technical subject matter that is being documented, within the framework of modern American English usage patterns. I have to concede on the fact that this is ultimately subjective and may (or may not - not sure) be specific to the en_US locale. Michael
  • RS Proxy Export Parameters?

    2023 python
    2
    1
    0 Votes
    2 Posts
    299 Views
    B
    False Alarm. Found it under C:\Program Files\Maxon Cinema 4D 2023\Redshift\res\description instead. Hehe. Closing this thread now.
  • HowTo set keyframes for PosXYZ/RotXYZ/ScaleXYZ with a script

    17
    1
    0 Votes
    17 Posts
    3k Views
    ferdinandF
    Hey @vannipo, GUI builder is inside C4D, isn't it? I am not sure, atm. There is no WYSIWYG GUI builder for dialogs in Cinema 4D anymore. A long time ago existed the classic API Resource Editor, but it is not published anymore by us. The Resource Editor you can find via CTRL + C in a modern Cinema 4D instance is an editor for maxon API resources, a different and newer GUI paradigm in Cinema 4D. When you want to implement a dialog, you will have to either write a resource file manually or use the methods of GeDialog to add elements at runtime, you could have a look at this posting where I recently lined out some basics. The Python GUI Manual is quite superficial at the moment, but we have some simple examples on GitHub. For learning dialog resource markup, I would recommend the Dialog Resource Manual. The most important point for an animator is to key the desired channel as fast as possible. [...] But, the pop-up idea is very interesting, and I will have a look [...] Yeah, I understood that you were after a very streamlined setup. When you want to make zero compromises, nine shortcuts are probably the best solution. The solution I proposed with the popup menu is a compromise of the number of shortcut keys to allocate and the speed with which keys can be generated. The advantage is here that the popup menu will always open under your mouse cursor no matter where it is, which will minimize mouse travel distances. But when you overpopulate the menu with all nine entries (you can also add separators if you want to), selecting the right item will probably become slow. So, if you want a good compromise, you could use three scripts (translate/rotate/scale) which each provide a popup for x, y, or z. Btw, is it possible to set a "real name" for a script? atm, everywhere it just shows the filename. You can supply a different name from its filename by adding file docstring containing Name-en-US: XXXX where XXX is the name of the plugin. This can also be done for description that will be displayed when you hover the command with Description-en-US: XXX. If you need to support other language please refer to Plugin Structure Manual which specify the different language code. Finally you can find an example within GitHub - script_custom_name_description.py Cheers, Ferdinand
  • 0 Votes
    8 Posts
    1k Views
    P
    Thanks for the good explanation.
  • [SOLVED] ARROWBUTTON resource not accessible for Python?

    5
    0 Votes
    5 Posts
    792 Views
    ferdinandF
    Great to hear! One thing I forgot to mention: For ICONID1 XXX and ICONID2 YYY you can use any of the built-in icon IDs as listed here. When you want to use your own icons, you must make sure the icon IDs are registered before the node which is using them in its description. Simply put the c4d.gui.RegisterIcon call before the RegisterXXXPlugin call of the plugin using them. Cheers, Ferdinand
  • Switch render engine to Redshift (In memory)

    python
    4
    0 Votes
    4 Posts
    898 Views
    ferdinandF
    Hi @everyone, just as an FYI, the example is slightly outdated. With 2023.0.0 or newer, there is no need to manually define a symbol for the Redshift renderer, as one can use the newly exposed VPrsrenderer symbol (c4d.VPrsrenderer in Python). I have updated the C++ example. Cheers, Ferdinand
  • Cinema 4D R2023 - c4d.plugins.RegisterObjectPlugin issue

    2023 python
    6
    0 Votes
    6 Posts
    1k Views
    M
    @baca said in Cinema 4D R2023 - c4d.plugins.RegisterObjectPlugin issue: Any suggestion how to properly handle that kind of issues -- just catch exception and warn user using message box somehow? Correct you can catch the OsError and check if there is the word 50 in the exception message. Would it be reasonable to switch to NodeData from ObjectData -- It depends of your plugin if this is at the end an ObjectData then it's irrelevant, if this is just an object that you store in a list in memory or in a custom GeListHead then NodeData is perfectly relevant. does RegisterNodePlugin has separate 50 plugins registrations? Yes each type have 50 plugins. What's the logic behind plugin initialization order -- alphabetical, date-based, random? Folders from g_additionalModulePath are iterated by alphabetical order and each files are then iterated by alphabetical order too. Cheers, Maxime.
  • 3D Mouse Slider Focus

    python windows r19 maxon api
    13
    1
    0 Votes
    13 Posts
    3k Views
    CairynC
    @charly CollieMouse rotates around the current selection or the explicit rotation center (the one you set with the INS shortcut). It will not rotate around the mouse pointer (I think... I implemented so many modes over time that I tend to forget the options...). The mouse pointer only exists in 2D space anyway so the actual rotation would happen around a projection of the mouse position into the scene, and if you move the mouse, the rotational center would change... not sure whether that is even a usable mode. The mode I'd recommend would be around the explicit center: Position the mouse, press INS (or whatever shortcut you use), and then use the 3D mouse to rotate around that. C4D shows the explicit center as green cross so you always know where it is. At the moment there is no R2023 version of CollieMouse anyway, so the point is moot. But you can reach me under cairyn (at) tigress (dot) com if you require specialty development.
  • CreateRepositoryFromUrl results in TypeError in 2023

    python 2023
    4
    0 Votes
    4 Posts
    675 Views
    T
    Hi @m_adam, this works perfectly. Thank you for your fast response.
  • How to use RemoveConnections?

    2023 python
    3
    0 Votes
    3 Posts
    296 Views
    B
    @Manuel Gotcha. Thanks for the clarification. Works as expected.
  • Simple Organisational Structure Generation Script

    2023 python
    6
    0 Votes
    6 Posts
    1k Views
    ManuelM
    @nealhulme you can have a look at our forum guidelines we have a section that explains how to mark your thread as a question. Then you can select a post as the answer or mark the thread solved. I forgot, welcome to the forum, i did not saw it was your first post. Cheers, Manuel
  • Skin Weights File Parser?

    python 2023
    3
    0 Votes
    3 Posts
    340 Views
    ManuelM
    hi, this is out of scope of the support and i never used configparser. Maybe maxime or Ferdinand will have some nice tips out of their head without having to investigate. I am happy you found a solution by pre-processing the file first. Cheers, Manuel
  • Complete Replica of a Native Objects UI?

    2023 python
    7
    1
    0 Votes
    7 Posts
    1k Views
    B
    @iplai @ferdinand Thanks for providing details especially the third party API. Seems like a handy utility library I'll see what I can do with it.
  • Merge Undos for the BeginTransaction() method?

    2023 python
    8
    0 Votes
    8 Posts
    1k Views
    B
    @ferdinand gotcha. thanks for clarification and adding links.
  • Wrong Polygon indices

    c++
    3
    1
    0 Votes
    3 Posts
    462 Views
    F
    Hi @m_adam, I just tested your suggestion and worked flawless, thank you very much. Cheers and happy holidays
  • 0 Votes
    2 Posts
    302 Views
    ManuelM
    hi, welcome to the forum and thanks for reaching us out. Thanks for the question and the clarity of it. The issue here is that you are changing the Time value of the keys but not their indexes. One function that could help you is SortKeysByTime but as you can see, it is marked as private. I am not sure why it is marked private here. There might have some cases where this function will not give you the correct result. you could create your own algorithm to sort those keys. Another solution could be to delete those keys and re-insert them, they will be sorted as you insert them. Cheers, Manuel
  • Load XGroup via Python

    python
    2
    0 Votes
    2 Posts
    340 Views
    M
    Hi @cgweasel unfortunately this is not exposed, Xpresso is no longer developed except for critical issues, it is very likely that this will not be added to the API. Cheers, Maxime.