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

    selection tag from selection tag

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 1.5k Views
    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.
    • H Offline
      Helper
      last edited by

      On 21/06/2018 at 01:52, xxxxxxxx wrote:

      Hi all. I am novice in phyton and the scripting too. I want to ask for advice
      I have Phyton generator and linked user data - source geometry and source selection tag
      I want to create new selection tag from souce selection tag.
      workflow: select souce polygons and then x% polygons from souce selection deselect

      when i use all polygons it works.

      My problem is (except im novice) How to select only souce selection. how to get count of source seletion polygons.

      Thank you

      code here:

      import c4d
      import random  
        
      def main() :  
        obj = op[c4d.ID_USERDATA,4]#link gemometry  
        #obj = op.GetDown()  
        if obj == None:  
            return  
         
        selSourceTag = op[c4d.ID_USERDATA,4]#selection tag source  
        if selSourceTag == None:  
           return  
          
        selectionTag = obj.GetTag(5673)#selection tag final  
        if selectionTag == None:  
            selectionTag = c4d.BaseTag(c4d.Tpolygonselection)  
            obj.InsertTag(selectionTag)   
              
        selection = selectionTag.GetBaseSelect()  
        selSource = selSourceTag.GetBaseSelect()      
        if obj.GetType() != c4d.Opolygon:  
            return   
             
        selection.selSource #######################how to select only souce selection  
        
        for i in xrange(selSource.GetPolygonCount()) :  
            if random.random() <= 1-op[c4d.ID_USERDATA, 2]:  
                selection.Deselect(i)  
        
                  
        op[c4d.ID_USERDATA, 1] = selectionTag  
                  
        #update  
        op.Message(c4d.MSG_UPDATE)  
        c4d.EventAdd()   
      
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 22/06/2018 at 09:28, xxxxxxxx wrote:

        Hi Peter.R first of all welcome at PluginCafe.

        I'm afraid, I need to ask you a little bit more time. I'll get back to you next Monday.

        Cheers,
        Maxime

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 22/06/2018 at 11:48, xxxxxxxx wrote:

          Hi Maxime.

          Thank you for the welcome.
          It does not matter at all. I have time.
          it will be nice if you find the time next week.

          Thank you again.

          Peter

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 25/06/2018 at 06:27, xxxxxxxx wrote:

            Hi Peter,

            I'm finally back to you. Since you want to synchronize a tag with another one, like a Tag Modifier will do (I know Tag modifier didn't exist in C4D). The most easier way of doing what you want to achieve is to use a Python Tag and not an ObjectGenerator (because in fact you don't modify, or create any new object).

            So you have to keep in mind, you are not allowed to modify the scene structure in a python tag ( add/remove/move objects/tags/shader etc...) but you can modify parameters. For more information about that, you can read Threading Information

            Here an example code of a python tag with some user data which are waiting for your selection tag.

            import random
              
            def main() :
                oriT = op[c4d.ID_USERDATA,1] #selection tag source
                rTresh = op[c4d.ID_USERDATA,2]
                resT = op[c4d.ID_USERDATA,3] #selection tag final
                
                # Check selection tag are defined
                if not oriT or not resT:
                    return
                
                ori = oriT.GetBaseSelect()
                res = resT.GetBaseSelect()
                
                # Copy or initial tag to the result
                ori.CopyTo(res)
                
                # Make sure to define a seed or you will get a different random for each execution of this tag
                random.seed(42)
                
                # Then randomly deselect some polygons
                for i in xrange(resT.GetObject().GetPolygonCount()) :
                    if not res.IsSelected(i) : continue
                    
                    if random.random() <= 1 - rTresh:
                        res.Deselect(i)
            

            And since res is a reference to the BaseSelect stored in the final tag, it will automatically update the tag.
            So we don't need any kind of update.

            If you have any questions you are welcome! 🙂
            Cheers,
            Maxime

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 25/06/2018 at 14:28, xxxxxxxx wrote:

              Hi Maxime,
              Thank you. I have a few questions.
              If in oriT is not all polygons -Loop in xrange (res.GetCount() ) doesnt work.
              So I change it to (mesh.GetPolygonCount()). (all polygons)

              Is possible to reduce this loop to oriT polygons (loop of list indexes)?

              "not allowed to modify the scene structure in a python tag" If I want to create selection tag:

              if not resT:
                    resT = c4d.BaseTag(c4d.Tpolygonselection)
                    resT.SetName("sel01")
                    mesh.InsertTag(resT)

              Is it allowed in Phyton generator?

              Thank you

                
              import c4d  
              import random  
                
              def main() :  
                oriT = op[c4d.ID_USERDATA,1] #selection tag source  
                rTresh = op[c4d.ID_USERDATA,2]  
                resT = op[c4d.ID_USERDATA,3] #selection tag final  
                mesh = op[c4d.ID_USERDATA,4] #selection mesh  
                 
                # Check selection tag are defined  
                if not oriT:  
                    return  
                 
                if not resT:  
                    resT = c4d.BaseTag(c4d.Tpolygonselection)  
                    resT.SetName("sel01")  
                    mesh.InsertTag(resT)  
                 
                ori = oriT.GetBaseSelect()  
                res = resT.GetBaseSelect()  
                 
                # Copy or initial tag to the result  
                ori.CopyTo(res)  
                 
                # Make sure to define a seed or you will get a different random for each execution of this tag  
                random.seed(42)  
                 
                # Then randomly deselect some polygons  
                for i in xrange(mesh.GetPolygonCount()) :  
                    if random.random() <= 1 - rTresh:  
                        res.Deselect(i)  
                          
                op[c4d.ID_USERDATA,3] = resT
              
              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                On 27/06/2018 at 00:55, xxxxxxxx wrote:

                Hi Peter,

                Originally posted by xxxxxxxx

                If in oriT is not all polygons -Loop in xrange (res.GetCount() ) doesn't work.
                So I change it to (mesh.GetPolygonCount()). (all polygons)
                Is possible to reduce this loop to oriT polygons (loop of list indexes)?

                You are right, sorry. Actually, BaseSelect store all elements (polygon/points) and simply define a value of 1 if it's selected or 0 if it's not.
                And there is no direct way to know which elements ID is selected so you have to iterate over all the objects, so you can do something like that

                for i in xrange(resT.GetObject().GetPolygonCount()) :
                	if not res.IsSelected(i) : continue
                	
                	if random.random() <= 1 - rTresh:
                		res.Deselect(i)
                

                Regarding your second question, no even in a generator is not allowed.
                Understand a generator like a scene within a document. So you can't create outside of it(actually you can, but it can cause some crash and instability, so it's really not recommended and should be avoided).
                But what you can do since a generator is like a mini-scene, is to create your object in memory, assign to this object a tag and then return this object from main() function of the python generator. Actually the function behind is ObjectData.GetVirtualObject if you want to have more informations.
                Then you will be able to assign a material to this generator, and in the selection, filter writes the name of the selection you created, and it will work.

                Hope it makes sense.
                If you have any other question, please ask! 🙂

                Cheers,
                Maxime

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