Group Details Private


  • RE: Plugin compiled on macOS Catalina for R23, not working on Big Sur?

    @kbar said in Plugin compiled on macOS Catalina for R23, not working on Big Sur?:

    @fwilleke80 I think setting the hardened runtime when you code sign solves the timestamp issue. I don’t set a timestamp.

    codesign --force --options runtime --sign 'Developer ID Application: YOURCOMPANYNAME' 'sdk/plugins/yourplugin/yourplugin.xlib'

    Thanks a lot Kent, for pointing this out!
    The one below is the string I use which, as said by Kent, doesn't need the timestamp because of the hardened runtime.
    codesign -f -s "Developer ID Application: <YOUR DEV ID>" --options runtime <binary file>.xlib

    Documentation updated accordingly

    posted in Cinema 4D Development
  • RE: SceneHook and object caches

    Hi @C4DS,

    well, in scenario two the sds IS your cache parent, so this is kind of to be expected. I understand your line of thinking, that the Cube is somehow the meat of this of this generator/input object pair, but in the end it is just another scenario than a deformer deformed object pair. You said it yourself, deformation is not the right term for SDS.

    Anyways, we will talk about it on Monday and someone else or maybe I have a light-bulb moment then. But for now I do not see a built in functionality to do that (you can of course cobble your own logic together by fetching the control-objects, but this probably going to be a bit messy).

    Have a nice weekend and cheers,

    posted in Cinema 4D Development
  • RE: ShowPopupDialog Freezes Cinema R21

    Hi @AndreAnjos,

    well are you sure that ShowPopupDialog() is actually the culprit? Because it would be my last guess at the moment and in the end just replacing one buggy part with another feature is not really our understanding of good support here ;) Since we cannot reproduce your problem, you have to do the debugging unfortunately yourself. What I would propose is:

    1. Copy your plugin code into an editor which does not have "fancy features", i.e., something like windows notepad, and save it with that editor as a txt file and rename it back to my_plugin.pyp again. So to make sure that you do not have any weird unicode-mishaps in your file.
    2. Reinstall Cinema 4D from scratch. I know this one sucks, but in the end you have to do it anyways, when you have exhausted all other options, so you might also just get it out of the way in the beginning.
    3. Sprinkle in some print statements to see which parts of your code are reached before Cinema does freeze (although you should not put to much faith into this, due to the way Python does unravel its console output, but trying does not hurt).
    4. Remove the GetTimer() implementation form your AOMessage and remove the body of CoreMessage() except for the return statement.
    5. Reintroduce in blocks your code, you could for example first add everything up to active_mat= ... and then up to result =.
    6. With the results of 4. try to pinpoint the call/statement which does cause Cinema 4D to freeze.

    For each step you have to check if it did change anything about the freezing.

    Your code in general is rather inconspicuous, so at least I cannot point anything out that would be the obvious culprit. The fact that you start and close an undo-block without using it is a bit weird, but should not freeze Cinema 4D. One rather far-fetched reason could be that you somehow corrupted the world-container of your installation permanently and now accessing it will freeze Cinema 4D. But then this should normally happen all the time, because Cinema 4D does access it all the time (and also in your SceneLoaderData plugin, since it does access the same part of the world container.

    So at least from my side this is all mostly speculation. The unfortunate truth of debugging is that you are always samerter after figuring it out ;)


    posted in Cinema 4D Development
  • RE: ShowPopupDialog Freezes Cinema R21

    Hi @AndreAnjos, hi @m_adam,

    @AndreAnjos said in ShowPopupDialog Freezes Cinema R21:

    Morning Maxime,

    Yes, it freezes with the code I provided.
    I've also tried the way that you mention above by running the c4d.SpecialEventAdd(1055684) and the same happens, as per my video below.

    Let me know if you need any other information.

    Thank you!


    I just tried it too on R21.207 and it does not freeze for me either (I just added the message id as a print out, not knowing there was already that "finished" statement).


    One thing you could do is to try to remove other plugins or scripts that are loaded by your Cinema 4D R21 installation, to make sure sure none of them is interfering with the plugin. When you have done this, you could also test, if opening a popup dialog in general, so something like this in the script manager,

    import c4d
    def main():
        menu = c4d.BaseContainer()
        menu.InsData(MENU_REPLACE_ASSETS, 'Replace Asset(s)')
        menu.InsData(MENU_REPLACE_MATERIALS, 'Replace Material(s)')
        menu.InsData(MENU_REPLACE_TAG, 'Replace Texture Tag(s)')
        result = c4d.gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS)
    if __name__ == '__main__':

    will freeze your installation.


    posted in Cinema 4D Development
  • RE: ShowPopupDialog Freezes Cinema R21

    Hi, Unfortunately, I'm not able to reproduce your issue with the code you provided.
    The only difference is that I'm on windows 20H2. But I don't expect this to be the issue, I will ask someone else to try to reproduce.

    Just to be sure If you copy-paste the code you provided us, does it freeze for you?


    posted in Cinema 4D Development
  • RE: ShowPopupDialog Freezes Cinema R21

    Hi @AndreAnjos unfortunately, I'm not able to make Cinema 4D R21 freezing by copying your plugin and executing it by calling: c4d.SpecialEventAdd(1055684) from the Python console.

    So on which os version? on which exact version of R21 are you (you can check in the about form)?

    In which context and how often are you calling SpecianEventAdd?

    posted in Cinema 4D Development
  • RE: SceneHook and object caches

    Hi @C4DS,

    thank you for reaching out to us. I had some trouble understanding the finer details of your question. Your DoRecursion method looks correct to me. One thing noteworthy pointing out for a SceneHook context is that one does not have the guarantee that the caches always have been built or are up-to-date, depending on where and when the SceneHook does intercept.

    What I do not quite understand is why you do bundle up deformer and SDS ("... including the original input object for the deformation/SDS ...", I assume SDS does stand for Subdivision Surfaces), since an SDS-object does not write its output to the deformed cache but the cache. Generally speaking, caches can be quite complex in Cinema, since you often use generators. And in this case the deformed caches can be buried deep within the cache of the generator. You can use either the C++ SDK examples ActiveObject plugin to get a better sense of the full complexity of Cinema's scene graph:


    or use a little script I did post here, which only does focus on printing the expanded BaseObject scene graph tree with caches to the console, which can be a bit easier to read on large caches.

    This seems to work, except that I ignore any polygon object which is not an input of a deform/SDS. So, how to distinguish between a polygon object which is an input and one which isn't an input for deform/SDS?

    Well, you use BIT_CONTROLOBJECT like you do in your code. It will be set by ObjectData nodes (registered with the correct flag) on the object they govern or are governed by. Generators will mark their input objects and themselves in this fashion and deformers will not mark themselves but the objects they deform. So for this scenario here:


    The expanded tree of the top null would look like this (the output is from my script):

    Null/Null (BIT_CONTROLOBJECT: False)
    	Null/Null returns 'None' for GetCache.
    	Null/Null returns 'None' for GetDeformCache.
    	children of Null/Null:
    		Polygon/Cube (BIT_CONTROLOBJECT: True)
    			Polygon/Cube returns 'None' for GetCache.
    			Polygon/Cube returns for GetDeformCache:
                                    # This is Polygon/Cube deformed by the deformer Bend/Bend.
    				Polygon/Cube (BIT_CONTROLOBJECT: False)
    					Polygon/Cube returns 'None' for GetCache.
    					Polygon/Cube returns 'None' for GetDeformCache.
    					Polygon/Cube has no children.
    			Polygon/Cube has no children.
    		Bend/Bend (BIT_CONTROLOBJECT: False)
    			Bend/Bend returns 'None' for GetCache.
    			Bend/Bend returns 'None' for GetDeformCache.
    			Bend/Bend has no children.

    This will get even more complex once you do include generators.

    How to find back the relation "original object" <-> "deformed object".

    It depends on what you would consider to be a "original object". Raw polygon objects, i.e. nodes of type Opolygon, will always directly hold their deformed cache, even if the deformer is not a direct child of them (see previous example) or when you have multiple consecutive levels of deformation. For generators this is not so easy, and I would say it is a bit a matter of opinion there what you would consider to be the original and what not. The important point here is that deformed caches then will be buried within the cache of the generator, since only editable point objects are processed for deformers (i.e., something that is hidden in the cache for a generator).

    As already stated, I am not quite sure what you are asking exactly for. So I hope this helps a bit. If I missed your point, I would kindly ask you to explain again what your goals are.


    posted in Cinema 4D Development
  • RE: Access GradientCustomGui in NodeData::GetDDescription

    Ok after more research the only workaround possible I found is to extend the CustomGui to handle it as you suggested.

    Since data are only stored on the CustomGui there is no real way to pass the data back to the description, since there is no CustomGui when data are accessed via description.


    posted in Cinema 4D Development
  • RE: Xcode warnings about internationalization and language


    while you can click each warning to enabling and migrating, i didn't found a solution to update all project at once. (in xcode at least)

    I've asked our tech team if you can safely migrate and enable that option and if they can come with a new kernel_app.
    I will be back with the answer :)


    posted in Cinema 4D Development
  • RE: How to get all elements from BaseSelect

    Hi @orestiskon,

    thank you for reaching out to us. The problem with your code is that you pass the number of selected elements as the second argument to BaseSelect.GetRange(). But the method actually does expect the maximum index there, i.e., the total number of points for a point selection. While this method via .GetRange() is a bit more performant, in Python you can also use .GetAll() and list comprehensions. For details see the attached example.


    """A simple example for how to iterate over point selections.
    As discussed in:
    import c4d
    def main():
        """Iterates over the selected objects and accesses their point selection.
        # Iterate over the selected objects.
        for obj in doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE):
            # Step over non-point objects.
            if not isinstance(obj, c4d.PointObject):
            # All the points of the point object.
            points = obj.GetAllPoints()
            # And their count.
            pointCount = obj.GetPointCount()
            # The point selection.
            selection = obj.GetPointS()
            # The selection state of all elements in the BaseSelect. This is
            # a list of booleans, e.g., [True, False, False, False] for a polygon
            # object with just one quad and the first point in it being
            # selected.
            state = selection.GetAll(pointCount)
            # We have to manually convert this to indices.
            indices = [eid for eid, value in enumerate(state) if value]
            # I.e., you can get all selected indices like this in one go:
            # [eid for eid, val in enumerate(selection.GetAll(pointCount)) if val]
            # Print some stuff out.
            print("Object:", obj.GetName())
            print("Indices of selected points:", indices)
            print("The corresponding points:", [points[i] for i in indices])
            # The number of selected elements in the selection.
            print ("selection.GetCount():", selection.GetCount())
            # The segments in the selection, this has nothing to do with the
            # topology, but is rather the number of consecutive selection index
            # "strips". E.g.: [True, True, False, True, True] would be two
            # segments.
            print ("selection.GetSegments():", selection.GetSegments())
            # You can also access the selected elements like you tried to.
            for segment in range(selection.GetSegments()):
                # But you have to pass in here the point count, i.e., the number
                # of total total possible indices, not the number of selected
                # elements.
                print(selection.GetRange(segment, pointCount))
    if __name__ == '__main__':
    posted in Cinema 4D Development