Py2 -> Py3 - CLR Argument Issue In Py3

Hello,

I have this working Py2 code with a GetPoint Custom class that makes use of dynamically setting a boolean value in the following line:

            bln = clr.Reference[bool](True)

Used then in the rc = line:

            bln = clr.Reference[bool](True)
            
            for i, obj in enumerate(self.TargetObjects):
                bbox = obj.Geometry.GetBoundingBox(True)
                rc = self.picker.PickFrustumTest(bbox, bln)
                if not rc: continue

I’ve added super for the overall class but cannot seem to get the clr method working for Py3.

This is the error I am dealing with:

No overload for method 'CLRModule.Reference{}' takes '1' arguments(<class 'bool'>)

I can remove the argument and just right it as:
bln = clr.Reference[bool]()
but this doesn’t execute the rest of the script correctly because the bool value gets funky or is being incorrectly set I guess.

Working Py2 Code:
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

import System
import clr

class MyGetPoint(Rhino.Input.Custom.GetPoint):
    
    def __init__(self, objs):
        self.TargetObjects = objs
        self.ClosestIndex = -1
        self.Color = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor
        
        self.SetCommandPrompt("hover object for info")
        self.SetCursor(Rhino.UI.CursorStyle.Default)
        self.EnableObjectSnapCursors(False)
        self.PermitElevatorMode(False)
        self.EnableTransparentCommands(False)
        self.PermitConstraintOptions(False)
        self.PermitOrthoSnap(False)
        self.AcceptString(False)
        self.AcceptNumber(False, False)
        self.EnableSnapToCurves(False)
        self.AcceptNothing(False)
        self.PermitObjectSnap(False)
        
        self.picker = Rhino.Input.Custom.PickContext()
        self.picker.PickStyle = Rhino.Input.Custom.PickStyle.PointPick
        self.picker.PickMode = Rhino.Input.Custom.PickMode.Shaded
    
    def GetClosestObjIndex(self, viewport, window_point):
        try:
            if not viewport: return
            if not window_point: return
            
            xform = viewport.GetPickTransform(window_point)
            self.picker.SetPickTransform(xform)
            
            self.ClosestIndex = -1
            bln = clr.Reference[System.Boolean](True)
            
            for i, obj in enumerate(self.TargetObjects):
                bbox = obj.Geometry.GetBoundingBox(True)
                rc = self.picker.PickFrustumTest(bbox, bln)
                if not rc: continue
                
                if rc == True:
                    self.ClosestIndex = i
                else:
                    self.ClosestIndex = -1

        except Exception as ex:
            print(ex)

    def OnMouseMove(self, e):
        self.GetClosestObjIndex(e.Viewport, e.WindowPoint)
        Rhino.Input.Custom.GetPoint.OnMouseMove(self, e)

    def OnDynamicDraw(self, e):
        try:
            if self.ClosestIndex >= 0:
                obj_guid = self.TargetObjects[self.ClosestIndex].Id.ToString()
                obj_type = self.TargetObjects[self.ClosestIndex].ShortDescription(False)
                obj_name = rs.ObjectName(obj_guid)
                obj_name = obj_name if obj_name else "unnamed"

                combined_text = r"Name: " + obj_name + "\nType: " + obj_type + "\nId: " + obj_guid
                text = combined_text.lower()

                e.Display.Draw2dText(text, self.Color, e.CurrentPoint, True, 16)
                
        except Exception as ex:
            print(ex)

def DoSomething():
    
    scriptcontext.doc.Objects.UnselectAll()
    scriptcontext.doc.Views.Redraw()
    
    obj_ids = rs.ObjectsByType(0, False, 3)
    if not obj_ids: return
    
    objs = [rs.coercerhinoobject(obj_id) for obj_id in obj_ids]
    
    gp = MyGetPoint(objs)
    get_rc = gp.Get()
    if get_rc == Rhino.Input.GetResult.Point:
        if gp.ClosestIndex >= 0:
            rs.SelectObject(obj_ids[gp.ClosestIndex])
        else:
            print("Nothing selected")

DoSomething()

Attempt to update for Py3 Code:
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

import clr


class MyGetPoint(Rhino.Input.Custom.GetPoint):

    def __init__(self, objs):
        super().__init__()
        self.TargetObjects = objs
        self.ClosestIndex = -1
        self.Color = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor

        self.SetCommandPrompt("Select object")
        self.SetCursor(Rhino.UI.CursorStyle.Default)
        self.EnableObjectSnapCursors(False)
        self.PermitElevatorMode(False)
        self.EnableTransparentCommands(False)
        self.PermitConstraintOptions(False)
        self.PermitOrthoSnap(False)
        self.AcceptString(False)
        self.AcceptNumber(False, False)
        self.EnableSnapToCurves(False)
        self.AcceptNothing(False)
        self.PermitObjectSnap(False)

        self.picker = Rhino.Input.Custom.PickContext()
        self.picker.PickStyle = Rhino.Input.Custom.PickStyle.PointPick
        self.picker.PickMode = Rhino.Input.Custom.PickMode.Shaded

    def GetClosestObjIndex(self, viewport, window_point):
        try:
            if not viewport:
                return
            if not window_point:
                return

            xform = viewport.GetPickTransform(window_point)
            self.picker.SetPickTransform(xform)

            self.ClosestIndex = -1
            bln = clr.Reference[bool]()  # Create a reference with an initial value

            for i, obj in enumerate(self.TargetObjects):
                bbox = obj.Geometry.GetBoundingBox(True)
                rc = self.picker.PickFrustumTest(bbox, bln)

                Rhino.RhinoApp.WriteLine(f"Testing object {i}: rc = {rc}, bln.Value = {bln.Value}")  # Debugging print

                if rc and bln.Value:
                    self.ClosestIndex = i
                    Rhino.RhinoApp.WriteLine(str(rc))
                    Rhino.RhinoApp.WriteLine(str(self.ClosestIndex))
                    break
                else:
                    self.ClosestIndex = -1

        except Exception as ex:
            print(ex)

    def OnMouseMove(self, e):
        self.GetClosestObjIndex(e.Viewport, e.WindowPoint)
        Rhino.Input.Custom.GetPoint.OnMouseMove(self, e)

    def OnDynamicDraw(self, e):
        try:
            if self.ClosestIndex >= 0:
                obj_id = self.TargetObjects[self.ClosestIndex].Id
                obj_name = rs.ObjectName(obj_id)
                if not obj_name:
                    obj_name = "Unnamed"

                obj_type = self.TargetObjects[self.ClosestIndex].ShortDescription(False)
                obj_guid = obj_id.ToString()

                text = f"Name: {obj_name}\nType: {obj_type}\nId: {obj_guid}"
                e.Display.Draw2dText(text, self.Color, e.CurrentPoint, True, 20)

        except Exception as ex:
            print(ex)


def DoSomething():

    scriptcontext.doc.Objects.UnselectAll()
    scriptcontext.doc.Views.Redraw()

    obj_ids = rs.ObjectsByType(0, False, 3)
    if not obj_ids:
        return

    objs = [rs.coercerhinoobject(obj_id) for obj_id in obj_ids]

    gp = MyGetPoint(objs)
    get_rc = gp.Get()
    if get_rc == Rhino.Input.GetResult.Point:
        if gp.ClosestIndex >= 0:
            rs.SelectObject(obj_ids[gp.ClosestIndex])
        else:
            print("Nothing selected")


DoSomething()


Has anyone come across this in Python 3 that could lend some pointers?

Thank you all for your help!

Okay sorry, after playing around with it more I got it working.

Sharing the solution here for anyone that stumbles on this in the future:

Py2:

# Create a reference with bool value argument
bln = clr.Reference[bool](False)  

Py3:

 # Create a reference without argument, then set value
bln = clr.Reference[bool]()
bln.Value = False