GetPoint, Double Option and KeyboardEvent


I’m using a GetPoint with multiple DoubleOptions, and I would like to change values using shortcuts.

I was checking KeyboardEvent, and I can catch the keys, but is there a way to don’t propagate it? If not, I can create my own keyboard hook.

Another question, is there a way to change the value of a Double option by code while is in execution? I change the value, but the command prompt still shows the original value.



I think you should have a look at dynamicdraw/preview:

import Rhino
import scriptcontext
import System.Guid
from System.Drawing import *

def OrientOnSrf():
    # Select objects to orient
    go = Rhino.Input.Custom.GetObject()
    go.SetCommandPrompt("Select objects to orient")
    go.SubObjectSelect = False
    go.GroupSelect = True
    go.GetMultiple(1, 0)
    if go.CommandResult()!=Rhino.Commands.Result.Success:
        return go.CommandResult()

    # Point to orient from
    gp = Rhino.Input.Custom.GetPoint()
    gp.SetCommandPrompt("Point to orient from")
    if gp.CommandResult()!=Rhino.Commands.Result.Success:
        return gp.CommandResult()
    # Define source plane
    view = gp.View()
    if not view:
        view = doc.Views.ActiveView
        if not view: return Rhino.Commands.Result.Failure

    source_plane = view.ActiveViewport.ConstructionPlane()
    source_plane.Origin = gp.Point()

    # Surface to orient on
    gs = Rhino.Input.Custom.GetObject()
    gs.SetCommandPrompt("Surface to orient on")
    gs.GeometryFilter = Rhino.DocObjects.ObjectType.Surface
    gs.SubObjectSelect = True
    gs.DeselectAllBeforePostSelect = False
    gs.OneByOnePostSelect = True
    if gs.CommandResult()!=Rhino.Commands.Result.Success:
        return gs.CommandResult()

    objref = gs.Object(0)
    # get selected surface object
    obj = objref.Object()
    if not obj: return Rhino.Commands.Result.Failure
    # get selected surface (face)
    surface = objref.Surface()
    if not surface: return Rhino.Commands.Result.Failure
    # Unselect surface
    def GetPointDynamicDrawFunc( sender, args ):
        rhobjref = go.Object(0)
        rhobj = rhobjref.Object()
        getrc, u, v = surface.ClosestPoint(args.CurrentPoint)
        getrc, target_plane = surface.FrameAt(u,v)
        xf = Rhino.Geometry.Transform.PlaneToPlane(source_plane, target_plane)
        delete_original = False
        #scriptcontext.doc.Objects.Transform(rhobj, xf, delete_original)
        args.Display.DrawObject(rhobj , xf)
    # Point on surface to orient to
    gp.SetCommandPrompt("Point on surface to orient to")
    gp.Constrain(surface, False)
    gp.AddOptionInteger +=
    gp.DynamicDraw += GetPointDynamicDrawFunc
    if gp.CommandResult()!=Rhino.Commands.Result.Success:
        return gp.CommandResult()

    # Do transformation
    rc = Rhino.Commands.Result.Failure
    getrc, u, v = surface.ClosestPoint(gp.Point())
    if getrc:
        getrc, target_plane = surface.FrameAt(u,v)
        if getrc:
            # Build transformation
            xform = Rhino.Geometry.Transform.PlaneToPlane(source_plane, target_plane)
            # Do the transformation. In this example, we will copy the original objects
            delete_original = False
            for i in range(go.ObjectCount):
                rhobj = go.Object(0)
                scriptcontext.doc.Objects.Transform(rhobj, xform, delete_original)
            rc = Rhino.Commands.Result.Success
    return rc



Thanks for the answer, but my problem is how to change the options in the command prompt from shortcuts. I don’t see any keyboard hook.



Do you mean you want to change the parts that get underlined automatically by the rhino command-line?


The shortcuts w, l and h are automatically generated, these can’t be overridden as far as I know. When you change a value and accept that the command-prompt should automatically update.


Is there a reason why you want to user shortcuts different from what the command-line gives you?

(command-line bits from live coding stream session 2, first command).


Yes, but I want to increase/decrease the values by pressing a key. For example, increase the Width value 0.1 pressing key one key, and decrease it with another key. Does it make sense? I think it is too slow for artistic designs to change manually.



I see what you are trying to do. At the moment I don’t think there is a way to do that such that the prompt updates properly, other than maybe posting the correct combination of keypresses you want to happen on your shortkey. In the case I showed above that’d be wenter15enter. Not sure how to do that in a good way though. Sounds like a lot of hackery will be involved.

1 Like

I wanted to do the same thing a long time ago, but my coding skills were by far not good enough back then and I haven’t tried since then, but had the exact same goal in mind. the plan was the following:

combine the preview thingy I posted earlier together with this code:

Call TestGetKey()

Sub TestGetKey
	Dim key
	Dim strUpSrf
	Dim arrPtOnSrf
	strUpSrf = rhino.GetObject("select UpSrf", 8)
	While Not IsNull(key)
		key = Rhino.GetKey("Press a key")
		If Not isNull(key) Then 
			If key(0) = "81" Then '---Q---
			End If
			If key(0) = "87" Then '---W---
				msgbox("MOVE UP/---W---")
			End If
			If key(0) = "69" Then '---E---
			End If
			If key(0) = "65" Then '---A---
				msgbox("TURN LEFT/ ---A---")
			End If
			If key(0) = "83" Then '---S---
				msgbox("MOVE DOWN/---S---")
			End If
			If key(0) = "68" Then '---D---
				msgbox("TURN RIGHT/---D---")
			End If
			'			If key(0) = "13" Then '---Enter---
			'			msgbox("Enter")
			'			End If
			Dim arrCursor
			arrCursor = Rhino.GetCursorPos
		End If
End Sub

(which I am not sure still works)

Rather than picking a ‘point on the surface to orient to’ using a stock GetPoint object, try creating a new class that inherits from GetPoint . In the new class you can construct the keyboard handler class, and have it post messages to that class.

For an example of how to inherit a new class from GetPoint , see the following developer sample.

If I remember correctly, back in the Matrix 5.0 days they had the exact function like this for orienting gems on surfaces pretty dynamically, but it would it was made with help of an external exe file.

hope this helps in case you decide to hack it together.

Hi @rafadelmolino,

Set GetBaseClass.AcceptNumber to true. Then just check the get result to see of the user entered a number.

– Dale