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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Polygon Selections with ObjectData Plugin

    Cinema 4D SDK
    python
    3
    6
    776
    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.
    • ?
      A Former User
      last edited by A Former User

      Hi!
      Are there any methods/examples for generating polygon selections with an ObjectData plugin similar to the Selections QuickTab of some Generator Objects?

      7b41588b-ca5c-4c6c-98b2-098ab7631f10-image.png

      Thank you 😃

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi,

        I don't think you can create the new CacheProxy tags in Python yet, at least not in a meaningful manner (haven't tried yet actually). But you can do it for sure the old school way. Just assign some selection tags to your cache. When assigning materials to the generator, Cinema will also look into cache to resolve material restriction selections. The code below can be inserted in a Python Generator and will allow you to assign materials with the selection "a" and "b". The attached file contains such setup.

        Cheers,
        zipit

        mat_selection_generator.c4d

        import c4d
        # Welcome to the world of Python
        
        
        def create_polygon_selection_tag(node, index):
            """Creates a polygon selection and returns it.
            
            Args:
                node (c4d.PolygonObject): The node.
                index (int): The polygon index.
            
            Returns:
                c4d.BaseTag: The selection tag.
            
            Raises:
                RuntimeError: When SMC failed.
            """
            # Select the passed polygon index in the node.
            selection = node.GetPolygonS()
            selection.DeselectAll()
            selection.Select(index)
            # Run SMC
            command = c4d.MCOMMAND_GENERATESELECTION
            mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION
            res = c4d.utils.SendModelingCommand(command=command,
                                                list=[node],
                                                mode=mode,
                                                bc=c4d.BaseContainer(),
                                                doc=c4d.documents.BaseDocument())
            if res is False:
                raise RuntimeError("Whoopsie!")
        
            # Get the last polygon selection tag on the node (which is the new
            # one). You might want to be a bit more careful here than me and
            # properly evaluate which one is the new tag.
            nid = c4d.Tpolygonselection
            tags = [tag for tag in node.GetTags() if tag.CheckType(nid)]
            return tags[-1] if tags else None
        
        
        def main():
            """Entry point.
            """
            node = c4d.PolygonObject(pcnt=6, vcnt=2)
            scale = 200
            u, v = c4d.Vector(1, 0, 0), c4d.Vector(0, 1, 0)
            # Points for first poly
            a = c4d.Vector()
            b = scale * u
            c = scale * (u + v)
            d = scale * v
            # Remaining points
            e = 2 * scale * u
            f = e + scale * v
            #         0  1  2  3  4  5
            points = [a, b, c, d, e, f]
            # Set points and set and create polygons.
            node.SetAllPoints(points)
            node.SetPolygon(0, c4d.CPolygon(0, 1, 2, 3))
            node.SetPolygon(1, c4d.CPolygon(1, 4, 5, 2))
            # We can instiate selection tags in Python, but we cannot set a
            # baseselect for them. So we have to use SMC.
            tag_a = create_polygon_selection_tag(node, 0)
            tag_b = create_polygon_selection_tag(node, 1)
            # Set the reference names of the tags so that we can adress them
            # in materials.
            tag_a[c4d.ID_BASELIST_NAME] = "a"
            tag_b[c4d.ID_BASELIST_NAME] = "b"
            # Farewell little polygon node ;)
            return node
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • ManuelM
          Manuel
          last edited by

          hi,
          with the proxy tag you would need the function SetRealTag that is not accessible from C++ nor Python.(And i'm going to ask why =))

          You can use a selected tag as ZipIt said, the material will "find" it anyway.

          The voronoi does it in another kind of way. It does create the tags in the generator so you can "drag and drop" them to a field, but you can't drag and drop them in another object.
          For that, you need to set the bits to NBIT_NO_DD.
          The Generator need to track what tag should be active/display (change bits to NBIT_OHIDE and track the tags with an array of BaseLinks.

          And there's some other kind of "hack".

          As @zipit said, doing it "the old way" is maybe enough for users and your health 🙂

          Cheers,
          Manuel

          MAXON SDK Specialist

          MAXON Registered Developer

          1 Reply Last reply Reply Quote 0
          • ?
            A Former User
            last edited by A Former User

            This is very helpful, thank you @zipit and @m_magalhaes! Thank you so much for the example, @zipit !

            So the 'old school way' would require the user to make the object editable? Is there any way to do something similar to the SetRealTag or CacheProxy methods of procedural selection tags? I'd like to somehow control the shading of my object without making it editable. Thanks!

            ferdinandF 1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand @A Former User
              last edited by ferdinand

              Hi,

              @blastframe said in Polygon Selections with ObjectData Plugin:

              So the 'old school way' would require the user to make the object editable?

              that depends on what the user is trying to do. For anything that only references the selection tag by name, e.g. a material tag, no, the user won't have to make the object editable, because Cinema will on its own include the cache of a generator object when looking for selection tags referenced by name. The file above demonstrates that.

              If the user wants to reference the tag anywhere, where an actual BaseLink to a selection tag is required, e.g. the deformer restriction tag thingy, forgot its name, then, yes, the old approach shown above will not work.

              Cheers,
              zipit

              MAXON SDK Specialist
              developers.maxon.net

              ? 1 Reply Last reply Reply Quote 0
              • ?
                A Former User @ferdinand
                last edited by A Former User

                @zipit

                Sorry, it embarrassingly didn't occur to me that your file example was working because I didn't see the Selection Tags as with the Generators. Thanks again for it! For the best user experience, there would be a proxy tag so the user can link & reference it by name. @m_magalhaes , any updates on the SetRealTag implementation in the SDK? I created a request for the SDK here: SetRealTag Request

                Thank you.

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