selection tag from selection tag

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()   

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

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

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

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

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