Selecting polygons while erasing previous selectio

On 15/01/2018 at 01:51, xxxxxxxx wrote:

Hello, 
I am trying to do a script that selects all the polygon islands inside a polygon object, and create a material for each one of them, 
what I did is select the last polygon index in a list, which contains all of my polygons then select connected polys, which seems to work fine. Then it remove those selected polygons from the main list (which doesn't seem to work properly, as it only does half of them then give me an error. Also it has to erase the previous selection when it iterates again, which doesn't seem to work. 
Any insight to fix this will be really appreciated :)

here is my script :

import c4d
from c4d import utils
import random
import math

def main() :
    r = lambda: random.randint(0,100) #random gen
    obj =doc.GetActiveObject() #selected object
    pc = obj.GetPolygonCount() #poly count
    all_p = obj.GetAllPolygons() #gets all polys
    sel= obj.GetPolygonS()
    ind = 12
    con = 0
    lis = [] #empty list to hold the values below
    while (con<pc) :
        con += 1
        sel.DeselectAll() 
        c = c4d.Vector(r()*0.01,r()*0.01,r()*0.01) #random color 
        sel.Select(len(all_p)-1) #select a polgon, and the code below is to select connected
        utils.SendModelingCommand(command = c4d.MCOMMAND_SELECTCONNECTED,
                                    list = [obj],
                                    mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                    bc = c4d.BaseContainer(),
                                    doc = doc)

si = obj.GetPolygonS().GetAll(pc) #get a list of all the selected polygons
        n = 0 #a number to test which polygon index is selected or not,a loop to check that below
        for i in si :
            if (i == 1) :
                lis.extend([n])
            n += 1
        tag = c4d.BaseTag(c4d.Tpolygonselection) #make a selection tag
        tag[c4d.ID_BASELIST_NAME]= "selection" +str(r())
        obj.InsertTag(tag)
        tags = tag.GetBaseSelect() #gets the current selection of that tag and below it sets a new selection
        mat = c4d.BaseMaterial(c4d.Mmaterial) #makes a new material
        doc.InsertMaterial(mat)
        mat[c4d.MATERIAL_COLOR_COLOR] = c
        tex = c4d.TextureTag()
        tex.SetMaterial(mat)
        tex[c4d.TEXTURETAG_PROJECTION]=c4d.TEXTURETAG_PROJECTION_UVW
        obj.InsertTag(tex)

for i in lis :
            tags.Select(i)
        tex[c4d.TEXTURETAG_RESTRICTION] = tag[c4d.ID_BASELIST_NAME]
    
        for x in lis :
            print x
            all_p.pop(len(all_p)-1)

c4d.EventAdd()

if __name__=='__main__':
    main()

On 16/01/2018 at 04:50, xxxxxxxx wrote:

Hi malohammad, thanks for writing us.

With reference to the issue reported, the error you're encountering it's actually related to a bad code design since you're attempting to pop an item from your polygons list (all_p) without checking that the index used to be greater than zero.

Even fixing the code with something like:

  
for x in lis :  
  print x  
  all_p_len = len(all_p)-1  
  if all_p_len >= 0:  
      all_p.pop(all_p_len)  

doesn't deliver the desired functionality.

I warmly suggest to review the code to achieve the desired functionality under a different design.

Best, Riccardo

On 16/01/2018 at 09:53, xxxxxxxx wrote:

Thanks for the reply, 
I will try to find another way around it, any suggestions would be great :)

On 17/01/2018 at 03:08, xxxxxxxx wrote:

Hi malohammad, with reference to strategy I warmly suggest you to avoid popping out already processed polygons out of all_p rather you could simply mark those processed ones and skip them in the early part of you while loop. This approach won't lead to any "out-of-sync" indexes between the values returned when selecting connected and the polygons residing in all_p.

Best, Riccardo

On 18/01/2018 at 10:06, xxxxxxxx wrote:

Hello and thanks again for the helpful answer, 
Regarding the "marking items" approach, is it done with the "dirty" method or using something like "map" modifier with .__getitem__? 
 Any insight to which direction I should use to mark items would be amazing:smile: