Thanks @mrhe ,
I did come across this but couldn’t get it to run in R8.
I added it as a command, compiled the plugin, and when I run it it “loads” but nothing after that happens so I gave up on it.
Without testing it was a bit hard for me to decipher which parts are relevant.
I attempted to convert that sample to Python 3 with … some luck. I got the custom gumball to show up but the dragging and get functionality I haven’t got working yet.
Here’s as far as I got with that code… should be able to run in editor without compiling anything.
#! python3
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
def create_cylinder(plane, radius, height):
"""Creates a cylinder and returns its GUID"""
circle = rs.AddCircle(plane, radius)
cylinder = rs.ExtrudeCurve(circle, rs.AddLine(Rhino.Geometry.Point3d(0, 0, 0), Rhino.Geometry.Vector3d(0, 0, height)))
rs.DeleteObject(circle)
return cylinder
def setup_radius_gumball(origin, direction):
"""Creates a gumball with a single X-axis control"""
gumball = Rhino.UI.Gumball.GumballObject()
gumball_frame = Rhino.Geometry.Plane(origin, direction)
gumball.SetFromPlane(gumball_frame)
# Configure appearance - only enable Z translation
gas = Rhino.UI.Gumball.GumballAppearanceSettings()
gas.RelocateEnabled = False
gas.RotateXEnabled = False
gas.RotateYEnabled = False
gas.RotateZEnabled = False
gas.ScaleXEnabled = False
gas.ScaleYEnabled = False
gas.ScaleZEnabled = False
gas.TranslateXEnabled = True
gas.TranslateXYEnabled = False
gas.TranslateYEnabled = False
gas.TranslateYZEnabled = False
gas.TranslateZEnabled = False
gas.TranslateZXEnabled = False
gas.MenuEnabled = False
return gumball, gas
def setup_height_gumball(origin, direction):
"""Creates a gumball with a single Z-axis control"""
gumball = Rhino.UI.Gumball.GumballObject()
gumball_frame = Rhino.Geometry.Plane(origin, direction)
gumball.SetFromPlane(gumball_frame)
# Configure appearance - only enable Z translation
gas = Rhino.UI.Gumball.GumballAppearanceSettings()
gas.RelocateEnabled = False
gas.RotateXEnabled = False
gas.RotateYEnabled = False
gas.RotateZEnabled = False
gas.ScaleXEnabled = False
gas.ScaleYEnabled = False
gas.ScaleZEnabled = False
gas.TranslateXEnabled = False
gas.TranslateXYEnabled = False
gas.TranslateYEnabled = False
gas.TranslateYZEnabled = False
gas.TranslateZEnabled = True
gas.TranslateZXEnabled = False
gas.MenuEnabled = False
return gumball, gas
def setup_display_conduit(gumball, appearance):
"""Creates and configures a gumball display conduit"""
conduit = Rhino.UI.Gumball.GumballDisplayConduit()
conduit.SetBaseGumball(gumball, appearance)
conduit.Enabled = True
return conduit
def main():
# Get base point for cylinder
base_point = rs.GetPoint("Select base point for cylinder")
if not base_point:
return
# Initial cylinder properties
radius = 5.0
height = 10.0
base_plane = rs.PlaneFromNormal(base_point, Rhino.Geometry.Vector3d(0, 0, 1))
# Create initial cylinder
cylinder_id = create_cylinder(base_plane, radius, height)
# Setup radius gumball at cylinder edge
radius_origin = rs.PointAdd(base_point, [radius, 0, 0])
radius_gumball, radius_appearance = setup_radius_gumball(radius_origin, Rhino.Geometry.Vector3d(0, 0, 1))
radius_conduit = setup_display_conduit(radius_gumball, radius_appearance)
# Setup height gumball at cylinder top
height_origin = rs.PointAdd(base_point, [0, 0, height])
height_gumball, height_appearance = setup_height_gumball(height_origin, Rhino.Geometry.Vector3d(0, 0, 1))
height_conduit = setup_display_conduit(height_gumball, height_appearance)
# Main interaction loop
while True:
# Get point with gumball
gp = rs.GetPoint("Drag gumball. Press Enter when done", True)
if gp is None: # User pressed Enter
break
# Check which gumball was picked
if radius_conduit.PickResult.Mode != Rhino.UI.Gumball.GumballMode.NONE:
# Update radius
new_radius = radius + (gp[2] - radius_origin[2])
if new_radius > 0:
rs.DeleteObject(cylinder_id)
radius = new_radius
cylinder_id = create_cylinder(base_plane, radius, height)
# Update radius gumball position
radius_origin = rs.PointAdd(base_point, [radius, 0, 0])
radius_gumball.SetFromPlane(Rhino.Geometry.Plane(radius_origin, Rhino.Geometry.Vector3d(0, 0, 1)))
elif height_conduit.PickResult.Mode != Rhino.UI.Gumball.GumballMode.NONE:
# Update height
new_height = height + (gp[2] - height_origin[2])
if new_height > 0:
rs.DeleteObject(cylinder_id)
height = new_height
cylinder_id = create_cylinder(base_plane, radius, height)
# Update height gumball position
height_origin = rs.PointAdd(base_point, [0, 0, height])
height_gumball.SetFromPlane(Rhino.Geometry.Plane(height_origin, Rhino.Geometry.Vector3d(0, 0, 1)))
sc.doc.Views.Redraw()
# Cleanup
radius_conduit.Enabled = False
height_conduit.Enabled = False
sc.doc.Views.Redraw()
if __name__ == "__main__":
main()