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!
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)
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?
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.