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