Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Reading Immutable Selection Tags

    Scheduled Pinned Locked Moved Cinema 4D SDK
    python
    3 Posts 2 Posters 34 Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D Offline
      Dimitris_Derm.
      last edited by Dimitris_Derm.

      How can I read data from Selection Tags created by SceneNodes modifiers like the Store Selection ?

      Seems like they don't work like the other selection tags.

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF Offline
        ferdinand @Dimitris_Derm.
        last edited by ferdinand

        Hello @Dimitris_Derm. ,

        Thank you for reaching out to us. Please follow our Support Procedures, especially regarding providing code and scene data alongside your questions. Because otherwise things can become a guessing game for us. It also often the case that things are more complicated than it seems, as the case here.

        About your Question

        When you talk about 'selection tags', I assume from the context that you actually mean selection proxy tags (denoted by the little link overlay icon). E.g., as here generated by the extrude object.
        13749476-8f97-400c-af06-411186aaad78-image.png

        Proxy selection tags exist because selection tags need a point object to work, when a selection tag sits on a generator, it becomes ambiguous to which point object inside the cache of the generator they belong. Proxies solve this by pointing to one or many actual selection tags in a cache (it is often the case that a proxy tag does not resolve to a singular discrete tag in the cache but to multiple tags).

        The proxy tag type class/interface is private as declared in the C++ API, i.e., one cannot interact directly with them (as a third party). But one can send MSG_GETREALTAGDATA to find the discrete tag(s) it points to.

        ⚠ The data returned by MSG_GETREALTAGDATA is by design data in caches. You can read data in caches, but you should never attempt to write data in caches, as caches are static by design, and violating this rule can lead to crashes.

        ⚠ What makes this more complicated in this case is that you use Neutron (Scene Nodes) which adds another layer of complexity. We would need here your existing code and a concrete scene to give an answer, as the approach shown below will likely not work there.

        Cheers,
        Ferdinand

        Result

        An extrude object which holds a proxy selection tag. In the console we can see the partial scene graph for the object. I have highlighted the line which is the actual selection tag inside the cache of the extrude object the proxy points to.

        ec1e1feb-d525-49c5-a800-4668aeb9abd4-image.png

        My scene: extrude.c4d

        Code

        """Demonstrates how to find the discrete selection tags which are pointed to by a selection proxy tag 
        on a generator.
        """
        
        import c4d
        import mxutils
        
        doc: c4d.documents.BaseDocument  # The currently active document.
        op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
        
        # The types of proxy tags which we want to find on the selected object.
        PROXY_TAG_TYPES: tuple[int, ...] = (
            c4d.Tcacheproxytagpointselection,
            c4d.Tcacheproxytagedgeselection,
            c4d.Tcacheproxytagpolyselection
        )
        
        def main() -> None:
            """Called by Cinema 4D when the script is being executed.
            """
            if op is None:
                return c4d.gui.MessageDialog('Please select an object.')
            
            # The proxy tags of #op. Proxy tags exist because selections (and some caches) only work directly
            # on a point object. A selection tag on a generator can be ambiguous, because it might not be 
            # clear which of the multiple point objects in the cache of the generator it should be applied 
            # to. Proxy tags solve this problem, as they point to one or multiple discrete selection tags 
            # in the cache of a generator, which should be used in place of the proxy.
            proxyTags: list[c4d.BaseTag] = [t for t in op.GetTags() if t.GetType() in PROXY_TAG_TYPES]
            if not proxyTags:
                return c4d.gui.MessageDialog('The selected object has no proxy tags.')
            
            # Print the partial scene graph of #op, so that we can see what is going on in the cache tree 
            # of it.We should see there the discrete selection tag(s) which are pointed to by the proxy tags 
            # of #op.
            print(mxutils.GetSceneGraphString(op))
            print("\n", "-" * 80, "\n")
        
            # Iterate over all proxy tags and find the discrete selection tags they point to, using the 
            # message c4d.MSG_GETREALTAGDATA. The result of this message is a dictionary, which contains 
            # references to the discrete selection tags in the cache of the generator, which are pointed 
            # to by the proxy tag.
            for proxyTag in proxyTags:
                res: dict = {}
                proxyTag.Message(c4d.MSG_GETREALTAGDATA, res)
                tagSymbol: str = mxutils.g_c4d_symbol_translation_cache.Get(proxyTag.GetType())[0]
                print(f"{proxyTag.GetName()}({tagSymbol}) points to: {res}")
        
            # NEVER modify the returned tags, as caches are by design static (but that is not physically 
            # enforced by Cinema 4D). Changing the content of caches can very easily lead to crashes, unless
            # you know exactly what you are doing. Reading data from caches is perfectly fine, though.
        
        if __name__ == '__main__':
            main()
        
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dimitris_Derm.
          last edited by

          Ah ! They are called Proxy Tags and I can see the actual tag with the MSG_GETREALTAGDATA ! Thank you ❤️

          1 Reply Last reply Reply Quote 0
          • First post
            Last post