• Using / copying object properties dialog

    Cinema 4D SDK python 2023
    5
    1
    0 Votes
    5 Posts
    911 Views
    P
    Thanks for the clear answer. I know the difference between description and dialog, but I was hoping I could re-use already defined description in a dialog. But I follow your advise and recreate the settings. Regards, Pim
  • 0 Votes
    3 Posts
    612 Views
    ThomasBT
    @ferdinand thank you very much
  • 0 Votes
    2 Posts
    529 Views
    ferdinandF
    Hello @fkenned1, Welcome to the Plugin Café forum and the Cinema 4D development community, it is great to have you with us! Getting Started Before creating your next postings, we would recommend making yourself accustomed with our Forum and Support Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are: Support Procedures: Scope of Support: Lines out the things we will do and what we will not do. Support Procedures: Confidential Data: Most questions should be accompanied by code but code cannot always be shared publicly. This section explains how to share code confidentially with Maxon. Forum Structure and Features: Lines out how the forum works. Structure of a Question: Lines out how to ask a good technical question. It is not mandatory to follow this exactly, but you follow the idea of keeping things short and mentioning your primary question in a clear manner. About your First Question Your question is a little bit ambiguous, and I am not quite sure what you want to be done here. To get something simple out of the way: Cinema 4D C4DAtom instances, the atomic type all classic API scene elements derive from, have parameters which are indexed by c4d.DescID keys. Cinema 4D does not have properties in its classic API model. I understood what you meant, just as an FYI. This is represented by the methods C4DAtom.GetParameter and .SetParameter. The methods GeListNode.__getitem__ and .__setitem__, i.e., the bracket syntax in Cube[c4d.PRIM_CUBE_SUBY], are just convenience wrappers around the C4DAtom methods. The parameter keys passed to these methods are internally always c4d.DescID, it is only the convenience methods __get/setitem__ which allow you to pass integers instead, e.g., write Cube[c4d.PRIM_CUBE_LEN,c4d.VECTOR_X] or Cube[1100, 1000] (both do the same). I went over the subject of parameter IDs in more detail here. The drag and drop behavior of the Python console is proprietary and not exposed, I also do not quite understand what you want to do with it inside a dialog. If you want to let a user reference an object in a dialog, as for example many objects do in Cinema 4D, you must use a BaseLink parameter. In dialogs you can do this with the CUSTOMGUI_LINKBOX custom gui. I have shown here how to do this. Letting a user reference a parameter in this manner is not possible. You could technically unpack parameter drag data (at least in C++, likely not in Python, have not checked though) to get hold of a dragged BaseList2D and traverse its description (possible in C++ and Python) of a node to figure out to which DescID for example the string "c4d.PRIM_CUBE_LEN, c4d.VECTOR_X" corresponds to. But I do not quite understand the purpose of all this? I am sure there is a less complicated way to achieve what you want to do. I would recommend sharing your code and explaining what you want to achieve on a high level, as the workflow you have in mind is either impossible or at least very labor intensive to implement. Cheers, Ferdinand
  • 0 Votes
    3 Posts
    747 Views
    M
    Ok, thanks Ferdinand your clarification shed some light on my problem. I convert the version to a float which is the culprit ... import sys if sys.version_info < (3, 2): print("This Plugin requires at least Python 3.2") thank you
  • Get all textures for a material

    Cinema 4D SDK
    9
    0 Votes
    9 Posts
    3k Views
    M
    Hello @del, without further questions or postings, we will consider this topic as solved by Wednesday 31/05/2023 and flag it accordingly. Thank you for your understanding, Maxime.
  • Github Example group_nodes_r26 is broken.

    Cinema 4D SDK sdk python 2023
    4
    1
    0 Votes
    4 Posts
    528 Views
    ferdinandF
    Hello @Dunhou, I noticed maxon api changed every version and almost the major part of sdk change log We are aware that this fact is disliked by especially technical artists. But the Nodes API is still under active development and probably will be for the intermediate foreseeable future. Some changes from time to time are therefore inevitable. But we usually do not just remove something, but first mark it as deprecated and then remove it one or two cycles later, giving third parties more time to adapt. For S26, GraphModelInterface::IsSelected in graph.h changed for example into this: [[deprecated("Use GraphModelHelper static functions")]] MAXON_METHOD Result<Bool> IsSelected(const GraphNode& node); The problem is that this information is not visible at all for Python developers and still could also be improved for C++. We are aware of the problem, and working on the quality of change notes is something we already did over the last cycles and are still doing. Mapping such information to Python is certainly something I would like to do, but my main focus was for now gathering C++ API change notes in a more consistent manner. For now, I would recommend having an eye on the C++ change notes as a Python developer. The color coded deprecated markup should make it fairly easy to find upcoming removals, see for example the 2023.2 C++ API change notes. We are still working on improving API change notes for C++ and Python, because we are aware that it is crucial to clearly communicate our intentions with an API. I for example would like to make such information more searchable or pull it into the relevant documentary units. I.e., pull change notes also into the class, method, etc. descriptions, which are the subject of change. But that will be very hard to do with our current solutions might therefore have to wait a bit. Cheers, Ferdinand
  • CUSTOMGUI_QUICKTAB trigger twice when click

    Cinema 4D SDK sdk python 2023 windows
    7
    0 Votes
    7 Posts
    598 Views
    ferdinandF
    hey @Gene, So, you were just trying to add information for future readers? That is of course very welcome and explains my inability to extract a question from your posting. I would not have been that generous with the word bug either. Since this has never been fixed, chances are high that we came to the same conclusion internally. In general, you should not expect Command calling patterns to make perfect sense in every case. There are multiple cases where Command is triggered more often than one would think at first glance. I would also not try to interpret some deeper sense into all that. Cheers, Ferdinand
  • 0 Votes
    3 Posts
    473 Views
    chuanzhenC
    @i_mazlov Thanks
  • 0 Votes
    3 Posts
    731 Views
    B
    @i_mazlov Gotcha. Thanks. Works as expected.
  • 0 Votes
    3 Posts
    974 Views
    mikeudinM
    Thank you @ferdinand !
  • Can I convert several PYP files to one PYPV file?

    Cinema 4D SDK 2023
    9
    0 Votes
    9 Posts
    2k Views
    B
    Closing the thread with the following conclusion. No native way to do it in C4D. Manually have to merge them then convert that one file to PYP. So have to manage separate project files. One for source ones and one for merging several PY files.
  • 0 Votes
    2 Posts
    208 Views
    ferdinandF
    Hello @chuanzhen, Thank you for reaching out to us. Thank you for pointing this out, half of the word "offline" was pointing towards the offline C++ documentation. I have updated the link. Cheers, Ferdinand
  • Detect CTRL + RightMouseButton in SceneHook

    Cinema 4D SDK r25 c++ 2023
    3
    0 Votes
    3 Posts
    806 Views
    C4DSC
    Thanks for taking the time to respond, even during the weekend. I must say this is quite embarrassing: I already had forgotten about the response in the other thread, and it's not even 3 weeks old. I sincerely apologize for wasting your time with this duplicate thread. I can confirm the GetInputState is working fine, no need to waste more of your time trying it out. Thanks again.
  • Python Generator use a script

    Cinema 4D SDK python 2023
    3
    0 Votes
    3 Posts
    524 Views
    K
    Thanks
  • Get Points and Polygons from Primitives

    Cinema 4D SDK 2023 python c++
    2
    0 Votes
    2 Posts
    568 Views
    M
    Hi @CJtheTiger primitives are generators that generate and holds a PolyonObject in there cache. So most of the time for simple primitive like a cube, to access its generated PolygonObject, you should first retrieve it's cache with the GetCache method. If you want a more indepth introduction to this topic please read SDK Example - Geometry Readme. Then if you want to cover more complex cases I suggest you to read geometry_caches Example. And if you want to visualize the cache and the scene structure I would highly recommend to take a look at the C++ Example - activeobject dialog. Finally regarding the spline creation, you can find all the information needed to create a spline in Python Example - SplineObject, if you have more question on the spline creation please open a new topic. Cheers, Maxime.
  • 0 Votes
    4 Posts
    1k Views
    ferdinandF
    Hello @derekheisler, Welcome to the Plugin Café forum and the Cinema 4D development community, it is great to have you with us! Getting Started Before creating your next postings, we would recommend making yourself accustomed with our Forum and Support Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are: Support Procedures: Scope of Support: Lines out the things we will do and what we will not do. Support Procedures: Confidential Data: Most questions should be accompanied by code but code cannot always be shared publicly. This section explains how to share code confidentially with Maxon. Forum Structure and Features: Lines out how the forum works. Structure of a Question: Lines out how to ask a good technical question. It is not mandatory to follow this exactly, but you follow the idea of keeping things short and mentioning your primary question in a clear manner. About your First Question Please excuse the slight delay and thank you for the community answer provided by @HerrMay. The core misconception in your code lies in the line objs = doc.GetObjects(), as it does not get a list of all objects in doc, but only the root level objects. Users are expected to do scene graph traversal on their own at the moment, there is no method which would do it for you. There are also other problems with your code, as for example trying to instantiate a BaseThread or using CallCommand (not a real problem but not recommended in most cases). There have been also multiple similar threads in the past: How do you collapse complex dependencies in order?: This is about implementing a connect and delete. How to traverse a GeListNode Tree?: This is about hierarchical traversal, i.e., getting all descendants and siblings for a node. There is also something that I would call branch traversal, it is much more complex and we have talked about it for example here. CAD Normal Tag flipped: Entirely different topic, but could give you an idea on how to realize a simple GUI for this. Finde below a simple example. Cheers, Ferdinand Result: [image: 1680193792635-collapse.gif] Code: """Demonstrates how to collapse all SDS objects in a scene. One could also make this more fancy with a GUI and undo steps, I did not do this here. """ import c4d doc: c4d.documents.BaseDocument # The active document. def IterNodes(node: c4d.GeListNode) -> c4d.GeListNode: """Yields all descendants and next-siblings of `node` in a semi-iterative fashion. """ if node is None: return while node: yield node # The recursion moving down. for descendant in IterNodes(node.GetDown()): yield descendant # The iteration in one level. node = node.GetNext() def Collapse(objects: list[c4d.BaseObject]) -> None: """Collapses all items in #objects as individual root nodes into singular objects. This function mimics the behaviour of the builtin (but unexposed) "Connect & Delete" command by first running the "CSTO" and then "JOIN" command. With setups complex enough, this can still fail due to the non-existent dependency graph of the classic API (when one does CSTO things in the wrong order). In 99.9% of the cases this will not be the case, but one should get the inputs with #GETACTIVEOBJECTFLAGS_SELECTIONORDER as I did below to give the user more control. (or alternatively do not batch operate). """ if len(objects) < 1: raise RuntimeError() doc: c4d.documents.BaseDocument = objects[0].GetDocument() doc.StartUndo() # CSTO all local hierarchies in #objects and replace these root nodes with their collapsed # counter parts. result = c4d.utils.SendModelingCommand(c4d.MCOMMAND_CURRENTSTATETOOBJECT, objects, c4d.MODELINGCOMMANDMODE_ALL, c4d.BaseContainer(), doc, c4d.MODELINGCOMMANDFLAGS_NONE) if not result or len(result) != len(objects): raise RuntimeError() for old, new in zip(objects, result): parent, pred = old.GetUp(), old.GetPred() doc.AddUndo(c4d.UNDOTYPE_DELETEOBJ, old) old.Remove() doc.InsertObject(new, parent, pred) doc.AddUndo(c4d.UNDOTYPE_NEWOBJ, new) # Join the CSTO results root by root object, and then replace the CSTO results with the final # collapsed result. JOIN is a bit weird when it comes to transforms, so we must store the # transform of the to be joined object, then zero it out, and finally apply it to the joined # result again. for obj in result: mg: c4d.Matrix = obj.GetMg() obj.SetMg(c4d.Matrix()) joined = c4d.utils.SendModelingCommand(c4d.MCOMMAND_JOIN, [obj], c4d.MODELINGCOMMANDMODE_ALL, c4d.BaseContainer(), doc, c4d.MODELINGCOMMANDFLAGS_NONE) if not joined: raise RuntimeError() parent, pred = obj.GetUp(), obj.GetPred() doc.AddUndo(c4d.UNDOTYPE_DELETEOBJ, obj) obj.Remove() new: c4d.BaseObject = joined[0] new.SetMg(mg) doc.InsertObject(new, parent, pred) doc.AddUndo(c4d.UNDOTYPE_NEWOBJ, new) doc.EndUndo() c4d.EventAdd() def main() -> None: """Runs the example. """ # Find all SDS objects in the scene. objectList: list[c4d.BaseObject] = [ n for n in IterNodes(doc.GetFirstObject()) if n.CheckType(c4d.Osds)] # Collapse all SDS objects we have found. for obj in objectList: # We have to check if #obj is still a valid reference because we could have already # collapsed the object away in a prior iteration; sds-objects can live inside sds-objects. if not obj.IsAlive(): continue # Collapse the object. Collapse([obj]) c4d.EventAdd() if __name__ == "__main__": main()
  • How to dynamically hide parameters

    Cinema 4D SDK python 2023
    2
    1
    0 Votes
    2 Posts
    638 Views
    ferdinandF
    Hello @kng_ito, Thank you for reaching out to us. Modifying the description of a node via NodeData.GetDDescription should only be done when NodeData.GetDEnabling is not sufficient. To hide a parameter, the field c4d.DESC_HIDE must be set to True. Find a simple example below. Cheers, Ferdinand Result: [image: 1680101928166-hide_param.gif] File: pc14487.zip Code: // The description defintion of the tag Texample. CONTAINER Texample { NAME Texample; INCLUDE Texpression; // The main "Tag" tab of the tag. GROUP ID_TAGPROPERTIES { // The element which is being hidden (or not). REAL ID_HIDDEN_ELEMENT { MIN 0.0; MAX 100.0; UNIT METER; STEP 0.001; CUSTOMGUI REALSLIDER; } // The parameter based on which the hidden element is shown or not. BOOL ID_HIDE_CONDITION {} } } """Implements a tag which dynamically hides and shows a parameter. """ import c4d import typing class ExampleTagData(c4d.plugins.TagData): """Implements a tag which dynamically hides and shows a parameter. """ # The plugin ID for the hook. ID_PLUGIN: int = 1060794 @classmethod def Register(cls) -> None: """Registers the plugin hook. """ if not c4d.plugins.RegisterTagPlugin( id=cls.ID_PLUGIN, str="Example Tag", info=c4d.TAG_EXPRESSION | c4d.TAG_VISIBLE, g=cls, description="texample", icon=c4d.bitmaps.InitResourceBitmap(c4d.Tdisplay)): print(f"Warning: Failed to register '{cls}' tag plugin.") def Init(self, node: c4d.GeListNode) -> bool: """Called to initialize a tag instance. Args: node: The BaseTag instance representing this plugin object. """ self.InitAttr(node, float, c4d.ID_HIDDEN_ELEMENT) self.InitAttr(node, bool, c4d.ID_HIDE_CONDITION) node[c4d.ID_HIDDEN_ELEMENT] = 50.0 node[c4d.ID_HIDE_CONDITION] = False return True def Execute(self, tag: c4d.BaseTag, doc: c4d.documents.BaseDocument, op: c4d.BaseObject, bt: c4d.threading.BaseThread, priority: int, flags: int) -> int: """Called when expressions are evaluated to let a tag modify a scene. Not used in this case. """ return c4d.EXECUTIONRESULT_OK def GetDDescription(self, node: c4d.GeListNode, description: c4d.Description, flags: int) -> typing.Union[bool, tuple[bool, int]]: """Called by Cinema 4D when the description of a node is being evaluated to let the node dynamically modify its own description. """ # Bail when the description cannot be not fully loaded. if not description.LoadDescription(node.GetType()): return False, flags # Define the ID of the parameter we want to modify and get the ID of the parameter which is # currently to be evaluated. paramId: c4d.DescID = c4d.DescID(c4d.DescLevel(c4d.ID_HIDDEN_ELEMENT, c4d.DTYPE_REAL, 0)) evalId: c4d.DescID = description.GetSingleDescID() # Bail when there is a to be evaluated parameter and our parameter is not part of or equal # to the evaluated parameter. if (evalId and not paramId.IsPartOf(evalId)): return True, flags # Get the description data container instance (GetParameter>I<) for the parameter we want to # modify. All changes made to the container will be directly reflected on the node. paramData: c4d.BaseContainer = description.GetParameterI(paramId) if paramData is None: return True, flags # Set the hidden state of the parameter ID_HIDDEN_ELEMENT based on the value of the # parameter ID_HIDE_CONDITION. paramData[c4d.DESC_HIDE] = node[c4d.ID_HIDE_CONDITION] return True, flags | c4d.DESCFLAGS_DESC_LOADED if __name__ == "__main__": ExampleTagData.Register()
  • 0 Votes
    9 Posts
    2k Views
    A
    Hi @Manuel I have checked the new update 2023.2.0 and the feature works just fine with custom bitmaps without any change from my side. Congrats with a very quick bugfix! This is very cool! Also it's great the half-year version 2023.2 doesn't need 3rd party plugin rebuild and recompile as in S24, S26. Thanks for this!
  • Python Tag how to hide a mogragh object

    Cinema 4D SDK python windows 2023
    7
    0 Votes
    7 Posts
    1k Views
    DunhouD
    @Manuel Oh, what a pitty! I know that I can dot it with a effector, but it is not a "all in one" solution for my convenient,but that's it , I will not spend times in it. Thanks for your research, and @HerrMay thanks for your enthusiastic answers ! Cheers~ DunHou
  • Crash when apply a Tag plugin.

    Cinema 4D SDK 2023 python windows
    7
    0 Votes
    7 Posts
    1k Views
    DunhouD
    Hey @ferdinand ,Thanks for your detailed explains forever. Now it is clear to read the res files , and you show me the Agent Ransack last year, I use this software for learn something , and the C++ document is also good for the res file, but some of the data is distribute anywhere , like BITMAPMUTTON , I remember that I search for no fading option for a long time, but in python document it has a user friendly position in sdk. Maybe a document improvement or more Github examples are both welcomed( seems lots of works ) Thanks for your patience! Cheers~ DunHou