Creating selection tags



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 11:41, xxxxxxxx wrote:

    How does one assign a polygon face to a selection tag using python? I seem to be getting an error when trying to use c4d.BaseSelect.Select on a CPolygon object. how exactyl does one get a CPolygon object into a TPolygonSelection tag?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 13:03, xxxxxxxx wrote:

    Can you please post a few lines or an example? The selection tag has functions to get the internal BaseSelect instance. This can be used to select edges/points/polygons.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 13:22, xxxxxxxx wrote:

    You don't set a Polygon to a BaseSelect, You do activate or deactivate the Index of a Polygon.

    BaseSelect().Select(index)
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 13:23, xxxxxxxx wrote:

    well, this is the code i have so far,

    < ="utf-8">
    def FindNormals(op) : #function to find direction of walls and assign to seperate selection tags
        polys = op.GetAllPolygons() #get list of polygons in op
        doc = c4d.documents.BaseDocument()
        i=0
        for poly in polys: #find normals

    pt_a = op.GetPoint(poly.a)
            pt_b = op.GetPoint(poly.b)
            pt_c = op.GetPoint(poly.c)
            pt_d = op.GetPoint(poly.d)
            vector1 = pt_a-pt_b
            vector2 = pt_b-pt_c
            normal = vector1.Cross(vector2)
            normal.Normalize()
            nx = normal.x
            ny = normal.y
            nz = normal.z
            if(nx!=0) :                                            #check x normal
                print "poly",i,poly,"is facing x to a degree of:",nx
                i+=1
            elif(ny!=0) :                                          #check y normal
                print "poly",i,poly,"is facing y to a degree of:",ny
                i+=1
            elif(nz!=0) :                                          #check z normal
                print "poly",i,poly,"is facing z to a degree of:",nz
                i+=1
            else:
                print "something went wrong"

    It essentially iterates through a list of CPolygon objects and finds out their normals. Then according to the direction of the normal(x,y,or z) I want to assign it to a selection tag based on it's facing direction, but I'm juts not sure I fully understand the process of adding a polygon face to a selection tag using python. just as a starting point, how does one turn a CPolygon object into a BaseSelect object?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 14:14, xxxxxxxx wrote:

    im still having a lot of trouble here. not sure why i cant understand this. I found the command in the SDK for:

    PolygonObject.GetPolygonS()

    Return the selected polygons.

    _<_t_>__Return type: BaseSelect
    Returns: A reference to the selected polygon structure._tr>
    and i can run this on my object, but it seems to return my entire polygon object, not a list of faces. i am not understanding how, given a polygon object, you can turn a list of it's polygon faces into a selection. 
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 14:20, xxxxxxxx wrote:

    No, it returns a BaseSelect instance.

    sel = op.GetPolygonS()   
    for i in xrange(op.GetPolygonCount()) :   
    sel.Select(i)
    

    is the same as:

    sel = op.GetPolygonS()   
    sel.SelectAll(op.GetPolygonCount())
    

    a selection is defined by Indieces and bits saying wether a Polygon with a specific index is selected or not.

    Remember that the returned BaseSelect instance is the original Instance. Toggling a bit in the Selection does already take affect on the object.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 15:02, xxxxxxxx wrote:

    ahhhhh, thanks nux. I think I'm on the right track now. ill be back if this doesnt work but it seems to be returning a baseSelect object which is what i needed! thanks!



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/06/2011 at 18:12, xxxxxxxx wrote:

    ok, so after a great deal of effort, i cannot seem to get the BaseSelection INTO the Selection Tag. I have the BaseSelection object and the tag, but i cannot seem to get the polygon information into the selection tag. Is there some command in the sdk i am not seeing in terms of setting and getting selections from selection tags? I tried using the call command for Set Selection, but it doesn't seem to have the right elements selected for that command to work. ill post a link to the scene file if anyone wants to take a look.

    http://www.sendspace.com/file/sqf2fa

    thanks for all the help guys! everything is starting to click and i would be nowhere without all the help. so thank you again!



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 22/06/2011 at 00:32, xxxxxxxx wrote:

    This is your code.

      
    def SelectWalls(op,param) : #function to find direction of walls and assign to seperate selection tags  
      polys = op.GetAllPolygons() #get list of polygons in op  
      doc = c4d.documents.BaseDocument()  
      i=0  
      for poly in polys: #funtion to find normals  
      
          pt_a = op.GetPoint(poly.a)  
          pt_b = op.GetPoint(poly.b)  
          pt_c = op.GetPoint(poly.c)  
          pt_d = op.GetPoint(poly.d)  
          vector1 = pt_a-pt_b  
          vector2 = pt_b-pt_c  
          normal = vector1.Cross(vector2)  
          normal.Normalize()  
          polyselx = op.GetPolygonS()  
          polysely = op.GetPolygonS()  
          polyselz = op.GetPolygonS()  
    #        print polyselection  
          nx = normal.x  
          ny = normal.y  
          nz = normal.z  
          if(nx!=0) :                                            #check x normal  
             # print "poly",i,poly,"is facing x to a degree of:",nx  
              polyselx.Select(i)  
              i+=1  
          elif(ny!=0) :                                          #check y normal  
             # print "poly",i,poly,"is facing y to a degree of:",ny  
              polysely.Select(i)  
              i+=1  
          elif(nz!=0) :                                          #check z normal  
             # print "poly",i,poly,"is facing z to a degree of:",nz  
              polyselz.Select(i)  
              i+=1  
          else:  
            #  print "something went wrong"  
              pass  
          i+=1  
      if param ==0:  
          return polyselx  
      if param ==1:  
          return polysely  
      if param ==2:  
          return polyselz
    

    1. Do not obtain the Selection ever and ever again in the Loop, this is redundant calling of functions and leads to higher resource neccessarity.
    Instead of putting     polyselx = op.GetPolygonS()    in the loop, put it outside, before it.
    2. Remember when I said that you obtain a real instance of the BaseSelect when using GetPolygonS() ?
    That means, calling the function 3 times and assigning the BaseSelect to 3 different variables, modifing one of the BaseSelect's will modify all as they point to the same BaseSelect instance.
    3. You don't need to call GetPolygonS() if you do not want to copy the selection to the Object's Polygonselection or do not want to obtain the selected Polygons. Just create another BaseSelect instance.

    from c4d import BaseSelect  
    mySelection = BaseSelect()  
    mySelection.Select(12) # Enable the Bit with index 12
    

    3.1 If you want to copy this selection to the Polygonselection:

    # code from above, plus:  
    mySelection.CopyTo(op.GetPolygonS()) # Copys the bits from 'mySelection' to the original Polygon BaseSelect instance
    

    Outside the Function, your code looks like this:

        x_faces = SelectWalls(cube2,0)  
      y_faces = SelectWalls(cube2,1)  
      z_faces = SelectWalls(cube2,2)
    

    Why calculating all stuff again and again and again ? Instead, return a tuple or list or dictionary !
    Instead of

    def SelectWalls(op,param) : #function to find direction of walls and assign to seperate selection tags  
      [ .... ]  
      if param ==0:  
          return polyselx  
      if param ==1:  
          return polysely  
      if param ==2:  
          return polyselz
    

    Use this:

    def SelectWalls(op) : #function to find direction of walls and assign to seperate selection tags  
      [ .... ]  
      return polyselx, polysely, polyselz
    
    x_faces, y_faces, z_faces = SelectWalls(op)
    

    But this is some Standart Python and does not have to do with Cinema 4D at all, I recommend to read some more Python (not Py4D) Documentation. 😉

    Copying selection to SelectionTag:
    1. Why do you want to copy it to a SelectionTag ?
    2. Well, pretty simple:

    tag = op.MakeTag(c4d.Tpolygonselection)  
    tag_sel = tag.GetBaseSelect()       # Wrong documented in the SDK, use:  
    op.GetPolygonS().CopyTo(tag_sel)    #  
                                      #   for i in dir(tag) :  
                                      #       if "sel" in i.lower() :  
                                      #           print i  
                                      #  
                                      # to print all attributes of 'tag' containing the word "sel"  
    

    Cheers,



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 22/06/2011 at 15:27, xxxxxxxx wrote:

    thanks nux. yeah a lot of this stuff is somewhat over my head😢, but i am reading up on python and slowly but surely things are making more and more sense. I really have no other use for python besides using it in c4d so that is why i am mostly jumping into using py4d. I know that my code is noob status, but one has to start somewhere. I have been reading up on python, But It doesnt really help me in terms of understanding how to use the c4d python SDK. For example, you recently helped me write this bevel function that works like a charm. but when i tried to modify that same function to run ExtrudeInner(changing the BC settings and the MCommands), it didn't work. So it seems that every sendModelingCommand requires a completely different setup? where is this adressed in the SDK? they only give one example and it looks nothing like the one you helped me with, so how did you know which way to set up the SendModelingCommand? How does one know whether to return "op" or to return "op.GetClone[]" or "op[0]"?

    #Bevel Function

    def Bevel(op,offset) :
        if (offset<=0) :
            return op
        bc = c4d.BaseContainer()
        bc[c4d.MDATA_BEVEL_OFFSET2] = offset
        bc[c4d.MDATA_BEVEL_MODE] = c4d.MDATA_BEVEL_MODE_LINEAR
        if (not op) | (not op.CheckType(c4d.Opolygon))| op.CheckType(c4d.Ospline) : return op
        doc = c4d.documents.BaseDocument()
        doc.InsertObject(op, None, None)
        print c4d.utils.SendModelingCommand(
                                  command = 450000005,#bevel
                                  list = [op],
                                  bc = bc,
                                  doc = doc,
                                  mode = c4d.MODIFY_EDGESELECTION )
        return op.GetClone()

    #-----------------------------------------------------------------------------------------------------

    #function to make object editable
    def MakeEditable(op) :
        if (not op) | op.CheckType(c4d.Opolygon) | op.CheckType(c4d.Ospline) : return op

    op = [op.GetClone()]
        doc = c4d.documents.BaseDocument()
        doc.InsertObject(op[0],None,None)
        op = c4d.utils.SendModelingCommand(
                                  command = c4d.MCOMMAND_MAKEEDITABLE,
                                  list = op,
                                 
     mode = c4d.MODELINGCOMMANDMODE_EDGESELECTION,
                                  doc = doc )
        return op[0]

    These two functions both use the SendModelingCommand in completely different ways. how the heck am i supped to figure out which to use and for which command, for example, Extrude Inner? 😠

    back to the selection tag... The reason I was trying to create a selection tag was to then use SendModellingCommand on just the polygons within the selection tag. is this the complete wrong way to go about this? is there a better way to apply a sendModeling command to a group of faces being generated by a python Generator?

    thanks again for the lengthy explanations. It is really helpful.🙂



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 22/06/2011 at 18:34, xxxxxxxx wrote:

    It might help if you went to my tutorial site:https://sites.google.com/site/scottayersmedia/scripting
    and watched the videos on the SendModeling Commands.
    They are in Coffee. But I explain a little bit about where they come from, and how they work in the videos. And it might help you get a bigger picture about them.

    You have to understand this about the SDK's. They are written for developer's...Not Users.
    You are expected to already know what you're doing before you use them.
    You have to know how to take the information from one section of the SDK. And apply it to another section of the SDK. Developers spend years just learning how to do that. 
    To make things even more difficult.
    We often need to jump back and forth between the Coffee, Python, and C++ SDK's to find the information we're looking for.
    The SDK's are full of good information. But they are not newbie friendly documents.

    For most cases. Using op(the object you want to edit) is the way to go.
    You only need to work on a clone if it makes sense to do that.
    For example:
    When you're working on an object inside of a generator or a tool plugin. Everything constantly runs in the code all the time. You can't tell it to convert an object to a polygon... then have C4D ignore that conversion code.
    So you sometimes need to be creative. Using a clone as a proxy to work on. Instead of working on the actual source object.
    It's a clever trick to get around the fact that the code is always running and grabbing your source object. And won't let you change it directly.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 22/06/2011 at 20:41, xxxxxxxx wrote:

    thanks for the link and explanation scott! i acctually had some luck recently and seem to have the send modelling command figured out now, but the videos are a great help regardless. I recognize that python is written for developers, but frankly, i dont care.😉 lol, i want to be able to make my own plugins and scripts goddammit!  anyway, I think if I took a look at the  C++ SDK instead of python, i might be able to answer some of my questions before i ask on here, but also, i see these Q/A's as a good way to put info online for people that are stuck with some of these things. regardless, Im going to go back i try to approach it from the C++ angle as well, and hopefully a lot of the questions i am having will fade.

    EDIT: Scott, your videos rule. you scrolling in and out of the OMG face was hilarious.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 22/06/2011 at 21:39, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    EDIT: Scott, your videos rule. you scrolling in and out of the OMG face was hilarious.

    Thanks.
    This coding stuff is supposed to be fun. But that often gets lost when you're "overloaded" (intentional coding pun there 😉)  with the technical mumbo-jumbo that gets thrown at you when trying to learn it.
    I try to make it as fun as i can. And show people that I'm often just as lost and frustrated as they are.

    -ScottA


Log in to reply