Skip to content

Instantly share code, notes, and snippets.

@sbaer
Created July 29, 2013 18:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sbaer/6106433 to your computer and use it in GitHub Desktop.
Save sbaer/6106433 to your computer and use it in GitHub Desktop.
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class SliderForm(Form):
def __init__(self):
self.__value_changed_callback = None
self.InitializeComponent()
self.__disable_events = False
self._trackBar1.Value = 10
self._trackBar2.Value = 10
def InitializeComponent(self):
self._btnOk = System.Windows.Forms.Button()
self._btnCancel = System.Windows.Forms.Button()
self._lbl1 = System.Windows.Forms.Label()
self._trackBar1 = System.Windows.Forms.TrackBar()
self._txtBox1 = System.Windows.Forms.TextBox()
self._trackBar2 = System.Windows.Forms.TrackBar()
self._lbl2 = System.Windows.Forms.Label()
self._txtBox2 = System.Windows.Forms.TextBox()
self._trackBar1.BeginInit()
self._trackBar2.BeginInit()
self.SuspendLayout()
#
# btnOk
#
self._btnOk.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
self._btnOk.DialogResult = System.Windows.Forms.DialogResult.OK
self._btnOk.Location = System.Drawing.Point(202, 98)
self._btnOk.Name = "btnOk"
self._btnOk.Size = System.Drawing.Size(75, 23)
self._btnOk.TabIndex = 6
self._btnOk.Text = "OK"
self._btnOk.UseVisualStyleBackColor = True
#
# btnCancel
#
self._btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
self._btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
self._btnCancel.Location = System.Drawing.Point(283, 97)
self._btnCancel.Name = "btnCancel"
self._btnCancel.Size = System.Drawing.Size(75, 23)
self._btnCancel.TabIndex = 7
self._btnCancel.Text = "Cancel"
self._btnCancel.UseVisualStyleBackColor = True
#
# lbl1
#
self._lbl1.Location = System.Drawing.Point(12, 15)
self._lbl1.Name = "lbl1"
self._lbl1.Size = System.Drawing.Size(69, 23)
self._lbl1.TabIndex = 0
self._lbl1.Text = "Ratio (even)"
#
# trackBar1
#
self._trackBar1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
self._trackBar1.AutoSize = False
self._trackBar1.Location = System.Drawing.Point(87, 12)
self._trackBar1.Maximum = 100
self._trackBar1.Name = "trackBar1"
self._trackBar1.Size = System.Drawing.Size(223, 30)
self._trackBar1.TabIndex = 1
self._trackBar1.TickStyle = System.Windows.Forms.TickStyle.None
self._trackBar1.ValueChanged += self.OnSliderValueChanged
#
# txtBox1
#
self._txtBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right
self._txtBox1.Location = System.Drawing.Point(316, 12)
self._txtBox1.Name = "txtBox1"
self._txtBox1.Size = System.Drawing.Size(42, 20)
self._txtBox1.TabIndex = 2
self._txtBox1.TextChanged += self.OnTextBoxChanged
#
# trackBar2
#
self._trackBar2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right
self._trackBar2.AutoSize = False
self._trackBar2.Location = System.Drawing.Point(87, 54)
self._trackBar2.Maximum = 100
self._trackBar2.Name = "trackBar2"
self._trackBar2.Size = System.Drawing.Size(223, 30)
self._trackBar2.TabIndex = 5
self._trackBar2.TickStyle = System.Windows.Forms.TickStyle.None
self._trackBar2.ValueChanged += self.OnSliderValueChanged
#
# lbl2
#
self._lbl2.Location = System.Drawing.Point(12, 57)
self._lbl2.Name = "lbl2"
self._lbl2.Size = System.Drawing.Size(69, 23)
self._lbl2.TabIndex = 3
self._lbl2.Text = "Ratio (odd)"
#
# m_txtBox2
#
self._txtBox2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right
self._txtBox2.Location = System.Drawing.Point(316, 54)
self._txtBox2.Name = "txtBox2"
self._txtBox2.Size = System.Drawing.Size(42, 20)
self._txtBox2.TabIndex = 4
self._txtBox2.TextChanged += self.OnTextBoxChanged
#
# SliderForm
#
self.AcceptButton = self._btnOk
self.CancelButton = self._btnCancel
self.ClientSize = System.Drawing.Size(370, 132)
self.Controls.Add(self._lbl1)
self.Controls.Add(self._trackBar1)
self.Controls.Add(self._txtBox1)
self.Controls.Add(self._lbl2)
self.Controls.Add(self._trackBar2)
self.Controls.Add(self._txtBox2)
self.Controls.Add(self._btnOk)
self.Controls.Add(self._btnCancel)
self.MaximizeBox = False
self.MinimizeBox = False
self.MinimumSize = System.Drawing.Size(300, 170)
self.Name = "SliderForm"
self.ShowInTaskbar = False
self.Text = "Slider Form"
self._trackBar1.EndInit()
self._trackBar2.EndInit()
self.ResumeLayout(False)
self.PerformLayout()
def OnSliderValueChanged(self, sender, e):
#__disable_events is used to keep from circular
#events being called
if( self.__disable_events!=True ):
self.__disable_events = True
self._txtBox1.Text = str(self._trackBar1.Value/10.0)
self._txtBox2.Text = str(self._trackBar2.Value/10.0)
self.__disable_events = False
if( self.__value_changed_callback!=None ):
val_even = self._trackBar1.Value/10.0
val_odd = self._trackBar2.Value/10.0
self.__value_changed_callback(val_even, val_odd)
def SetValueChangedCallback(self, callback_object):
self.__value_changed_callback = callback_object
def OnTextBoxChanged(self, sender, e):
#__disable_events is used to keep from circular
#events being called
if( self.__disable_events!=True ):
self.__disable_events = True
try:
self._trackBar1.Value = float(self._txtBox1.Text) * 10.0
self._trackBar2.Value = float(self._txtBox2.Text) * 10.0
except:
self._txtBox1.Text = str(self._trackBar1.Value/10.0)
self._txtBox2.Text = str(self._trackBar2.Value/10.0)
self.__disable_events = False
import sliderform #SliderForm defined in SharpDevelop
import rhinoscriptsyntax as rs
import Rhino
import System.Drawing
import scriptcontext
import System.Windows.Forms
class SliderFormController():
"""Hook up UI of the SliderForm with some Rhino specific actions"""
def __init__(self, curve_ids, dialog):
# tell the SliderForm about a function to call when the slider values change
dialog.SetValueChangedCallback(self.UpdateTempCurves)
# Set up display conduit events to allow drawing of temporary preview
# geometry while the values are being adjusted by the user
#
# CalculateBoundingBox event is used to adjust the view's clipped bounds.
# Preview geometry may be outside the area of the bounding box of geometry
# in the document and therefore may be clipped if we don't adjust the bbox
Rhino.Display.DisplayPipeline.CalculateBoundingBox += self.OnCalcBoundingBox
# DrawForeground event is used to actually draw some temporary geometry on top
# of everything else. Depth writing/testing are off at this stage so all
# geometry is drawn on top
Rhino.Display.DisplayPipeline.DrawForeground += self.OnDrawForeground
# Get notified of when the form closes so we can remove our conduits
dialog.FormClosed += self.OnSliderFormClosed
# temp_curves and temp_curves_bbox are used for dynamic display
self.__temp_curves = []
self.__temp_curves_bbox = None
# original_curves is a list of (id, centroid, points) for each curve
# provided in the constructor. This is the information we need to
# quickly construct our temp_curves
self.__original_curves = []
for curve_id in curve_ids:
# curve_id is a Guid. Try to get the Curve geometry from this Guid
objref = Rhino.DocObjects.ObjRef(curve_id)
curve_geometry = objref.Curve()
objref.Dispose()
if( curve_geometry!=None and curve_geometry.IsClosed ):
mp = Rhino.Geometry.AreaMassProperties.Compute(curve_geometry)
rc, points = curve_geometry.TryGetPolyline()
if( rc ): self.__original_curves.append( (curve_id, mp.Centroid, points) )
def OnSliderFormClosed(self, sender, e):
# Form has closed. Remove our display conduit
Rhino.Display.DisplayPipeline.DrawForeground -= self.OnDrawForeground
Rhino.Display.DisplayPipeline.CalculateBoundingBox -= self.OnCalcBoundingBox
scriptcontext.doc.Views.Redraw()
def OnDrawForeground(self, sender, e):
# This function is called while updating viewports. Try not to perform
# too many calculations in here to minimize display performance hit.
# Draw each temp_curve in red and a "control" polygon in feedback color
curve_color = System.Drawing.Color.Red
feedback_color = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor
for points, curve in self.__temp_curves:
e.Display.DrawCurve(curve, curve_color, 1)
e.Display.DrawDottedPolyline( points, feedback_color, True )
e.Display.DrawPoints(points, Rhino.Display.PointStyle.ControlPoint, 2, feedback_color)
def OnCalcBoundingBox(self, sender, e):
# Update the boundingbox to include our temporary curves
if(self.__temp_curves_bbox!=None):
e.IncludeBoundingBox(self.__temp_curves_bbox)
def UpdateTempCurves(self, ratio_offset_even, ratio_offset_odd):
self.__temp_curves = []
self.__temp_curves_bbox=None
for id, centroid, cvs in self.__original_curves:
# "cook" up a temp_curve from the original curve data
temp_points = []
count = len(cvs)
for index, cv in enumerate(cvs):
vector = cv - centroid
# use %2 for even/odd test
if( index%2 == 0 or index==(count-1)):
vector *= ratio_offset_even
else:
vector *= ratio_offset_odd
point = centroid + vector
temp_points.append(point)
temp_curve = Rhino.Geometry.Curve.CreateControlPointCurve(temp_points, 3)
if( temp_curve!=None ):
self.__temp_curves.append((temp_points,temp_curve))
if( self.__temp_curves_bbox==None ):
self.__temp_curves_bbox = temp_curve.GetBoundingBox(False)
else:
self.__temp_curves_bbox = Rhino.Geometry.BoundingBox.Union( self.__temp_curves_bbox, temp_curve.GetBoundingBox(False))
scriptcontext.doc.Views.Redraw()
def AddCurvesToDocument(self):
# add the temp_curves to the document so they become "real" Rhino geometry
for points, curve in self.__temp_curves:
scriptcontext.doc.Objects.AddCurve(curve)
scriptcontext.doc.Views.Redraw()
def main_function():
"""
main function that runs for this script when it is run as __main__
Returns: True or False indicating success or failure
"""
# get a list of curves - use a custom filter function to
# not allow anything but closed polylines
def onlyclosedpolylines( rhino_object, geometry, component_index ):
if( isinstance(geometry, Rhino.Geometry.Curve) ):
if( geometry.IsPolyline() and geometry.IsClsed ): return True
return False
curves = rs.GetObjects("pick curves (polylines.planar.closed)", rs.filter.curve, custom_filter = onlyclosedpolylines)
if( curves!=None ):
# create the SliderForm and hook a "controller" object to it
dialog = sliderform.SliderForm()
controller = SliderFormController(curves, dialog)
# Show our dialog in a semi-modal way.
if( Rhino.UI.Dialogs.ShowSemiModal( dialog ) == System.Windows.Forms.DialogResult.OK ):
controller.AddCurvesToDocument()
return True
return False
if( __name__ == "__main__" ):
main_function()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment