Dynamic Drawing of Lines Based on Chosen Points



I’m looking to do something in python which is similar to the top example shown here, where the sample function
GetPointDynamicDrawFunct (sender, args) :
is defined.

I want to expand on that functionality and dynamically draw a second line based on where I pick the first point and it shows me the additional line before I choose second point. For instance if I picked a point A, and then moved my cursor to point B, and before I clicked it was dynamically drawing a line perpendicular (call it C->D) to vector A->B passing through point B, and it’s length was based on the length of A->B (which obviously wouldn’t yet be defined).

The problem I see is there would have to be scripted calculations going on to define the length of C->D and dynamically draw it in the middle of the Display.DrawLine.

Any ideas of whether not this is possible? I don’t fully understand the Dynamic Drawing functionality yet. Thanks in advance!


Custom Preview Display in Python(Grasshopper)
(Steve Baer) #2

I think this may be what you are looking for

import rhinoscriptsyntax as rs
import Rhino
import System.Drawing.Color
import math

def CustomPerpLine(point_a):
    # Color to use when drawing dynamic lines
    line_color_1 = System.Drawing.Color.FromArgb(255,0,0)
    line_color_2 = System.Drawing.Color.FromArgb(0,255,0)

    # This is a function that is called whenever the GetPoint's
    # DynamicDraw event occurs
    def GetPointDynamicDrawFunc( sender, args ):
        point_b = args.CurrentPoint
        #draw a line from the first picked point to the current mouse point
        args.Display.DrawLine(point_a, point_b, line_color_1, 1)
        line = Rhino.Geometry.Line(point_a, point_b)
        length = line.Length
        cplane = plane = args.Viewport.GetConstructionPlane().Plane
        angle = math.radians(90)
        xform = Rhino.Geometry.Transform.Rotation(angle, cplane.Normal, point_b)
        args.Display.DrawLine(line.From, line.To, line_color_2, 1)

    # Create an instance of a GetPoint class and add a delegate
    # for the DynamicDraw event
    gp = Rhino.Input.Custom.GetPoint()
    gp.DynamicDraw += GetPointDynamicDrawFunc
    if( gp.CommandResult() == Rhino.Commands.Result.Success ):
        pt = gp.Point()
        rs.AddLine(point_a, pt)

if( __name__ == "__main__" ):
    #get the first point
    point_a = rs.GetPoint("point A")
    if point_a:


Steve - this is awesome thank you for an incredibly quick reply. I understand much better what’s going on now.

The DynamicDraw is built into the GetPoint class and every time that event occurs it re-does the math (i.e. every time you move the mouse it recalls the defined GetPointDynamicDrawFunc, correct?

I’m confused as to what the sender and args arguments being passed do as I was under the impression that function was not predefined. Are these something in the background pre-defined in RhinoCommon?

(Steve Baer) #4

Yes every time the mouse is moved an event is fired (DynamicDraw event). This event is wired up to the GetPointDynamicDrawFunc using the += syntax

Events in .NET (RhinoCommon) call functions that need a certain number of arguments. The (sender, args) arguments are pretty typical when you work with .NET events. You almost never deal with sender; the args in this case are GetPointDrawEventArgs which are what you use to figure out where the mouse is and functions to perform drawing.


Roger - Thanks Steve i’ll continue looking at that.

Best place for documentation of this is the RhinoCommon SDK -> http://4.rhino3d.com/5/rhinocommon/


(Steve Baer) #6

And here on discourse or the wiki at