Yannick: ViewportSelect documentation



  • On 16/01/2014 at 11:42, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   15 
    Platform:   Windows  ;  Mac  ;  
    Language(s) :

    ---------
    Yannick,
    There's some typos in the examples for this class.

    infopoint = viewportselect.GetPixelInfoPoint(x, y)
    Should be
    infopoint = ViewportSelect.GetPixelInfoPoint(x, y)

    I'm also having a hard time getting ViewportSelect to work.
    It's giving me this error: TypeError: 'c4d.PolygonObject' object is not iterable
    ViewportSelect is working fine for me in C++. But not in Python.

    Example:

    #This is a python script that gets the mouse's position with a radius option for making selections  
    #The radius helps you to select things without having to be exactly on the thing you're trying to select  
    #Put the code in a pytag  
      
    import c4d  
    def main() :  
        
      obj = op.GetObject()      #The object the pytag is on(converted to editable)  
        
      radius = 10               #Change the radius value as desired  
      radSqr = radius * radius  
      if radSqr < 1.0: return False    
      
      msg = c4d.BaseContainer()  
      while c4d.gui.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, msg) :  
          if msg[c4d.BFM_INPUT_VALUE] == 0: break  
        
          mouse_x = msg[c4d.BFM_INPUT_X]  
          mouse_y = msg[c4d.BFM_INPUT_Y]  
            
          #Get the dimensions of the editor window(this includes the left and top icon borders too)  
          bd = doc.GetActiveBaseDraw()  
          dimension = bd.GetFrame()  
          dimension["cl"], dimension["ct"], dimension["cr"], dimension["cb"]        
          left  = dimension["cl"]  
          top   = dimension["ct"]  
          right = dimension["cr"]  
          bottom= dimension["cb"]      
        
          eWinWidth = right - left + 1    #The width of the editor window  
          eWinHeight = bottom - top + 1   #The height of the editor window   
      
      
          #####################################################################################  
          #This code block sets up the radius around the mouse's current position  
          #x1 is amount of screen pixels to check towards the left of the mouse   
          #x2 is amount of screen pixels to check towards the right of the mouse   
          #y1 is amount of screen pixels to check towards the top of the mouse      
          #y2 is amount of screen pixels to check towards the bottom of the mouse  
          #####################################################################################  
          #Gets the mouseX position - the radius value (but returns 0 if value is less than zero)   
          x1 = int(c4d.utils.Clamp(0, mouse_x - radius, mouse_x - radius))  
      
          #Gets the mouseX position + the radius value (but returns the screen width if value is more than the screen width)  
          x2 = int(c4d.utils.Clamp(mouse_x + radius, eWinWidth - 1, mouse_x + radius))  
      
          #Gets the mouseY position - the radius value (but returns 0 if value is less than zero)  
          y1 = int(c4d.utils.Clamp(0, mouse_y - radius, mouse_y - radius))   
      
          #Gets the mouseY position + the radius value (but returns the screen height if value is more than the screen height)  
          y2 = int(c4d.utils.Clamp(mouse_y + radius, eWinHeight - 1, mouse_y + radius))  
          #####################################################################################     
      
          vps = c4d.utils.ViewportSelect()  
          vps.Init(eWinWidth, eWinHeight, bd, obj, c4d.Mpoints, True, c4d.VIEWPORTSELECTFLAGS_0)  
            
          #Loop through the pixels in the screen in a matrix like fashion  
          #By getting the pixels using Rows & Columns using 2 for loops  
          for x in range(x1, x2) :  
              for y in range(y1, y2) :   
                  rSqrDist = (x - mouse_x)*(x - mouse_x) + (y - mouse_y)*(y - mouse_y)  
                  if rSqrDist > radSqr: continue                 
                  infopoint = vps.GetPixelInfoPoint(x, y)  
                  if infopoint.op == obj:  
                      #This code will select the points on the object if they're within the radius range  
                      bs = c4d.BaseSelect()  
                      bs = obj.GetPointS()  
                      bs.Select(infopoint.i)
    

    Any idea why it works in C++ but not in Python?
    My C++ code is almost identical to this Python code. Except that it's used in a tool plugin.

    -ScottA



  • On 16/01/2014 at 14:12, xxxxxxxx wrote:

    Never mind. I found the problem.
    In C++ we use a polygon type object in the vps.Init() params.
    But in Python you guys changed it to require a list of active objects instead.

    -ScottA



  • On 17/01/2014 at 00:02, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Never mind. I found the problem.
    In C++ we use a polygon type object in the vps.Init() params.
    But in Python you guys changed it to require a list of active objects instead.

    In C++ there are 2 methods Init() in ViewportSelect:
    One that takes an object only (BaseObject) and one that takes a list of objects (AtomArray).



  • On 17/01/2014 at 08:24, xxxxxxxx wrote:

    Yeah. That's what tripped me up for a second.
    Apparently the Python version doesn't allow us to use a single object in the params. like C++ does.

    -ScottA


Log in to reply