Dynamic Drawing of Lines Based on Chosen Points


#1

Hi,

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!

-Chris


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)
        line.Transform(xform)
        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
    gp.Get()
    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:
        CustomPerpLine(point_a)

#3

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.


#5

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