Skip to content

Instantly share code, notes, and snippets.

@yatt
Created October 21, 2011 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yatt/1303534 to your computer and use it in GitHub Desktop.
Save yatt/1303534 to your computer and use it in GitHub Desktop.
IronPython - VB.NET Interoperation
Imports Microsoft.Scripting
Imports Microsoft.Scripting.Hosting
Imports IronPython.Hosting
Public Class Form1
Dim beziers As New List(Of Object)
Dim working As ArrayList = Nothing
Dim ctrls As New List(Of Point)
Dim index() As Integer = {-1, -1}
Dim focuses() As Integer = {-1, -1}
Const dimention As Integer = 3 ' ベジェ曲線の次元
' IronPython
Dim engine As ScriptEngine
Dim scope As ScriptScope
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
beziers.Clear()
working = Nothing
ctrls = New List(Of Point)
index(0) = -1
index(1) = -1
focuses(0) = -1
focuses(1) = -1
Refresh()
End Sub
Private Sub Panel1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel1.Click
If (Control.ModifierKeys And Keys.Shift) = Keys.Shift Then
Exit Sub
End If
If working Is Nothing Then
working = New ArrayList
End If
' 点の記録
Dim p As Point = Panel1.PointToClient(Cursor.Position)
working.Add(p)
' ベジェ曲線への記録
If working.Count = dimention + 1 Then
' IronPython.Runtime.List(Of IronPython.Runtime.PythonTuple) に自動変換してくれるかな?
Dim lst As New IronPython.Runtime.List
For Each p In working
Dim item As New IronPython.Runtime.List
item.Add(p.X)
item.Add(p.Y)
lst.Add(item)
ctrls.Add(p)
Next
Dim args() As Object = {lst, 0.01}
Dim bezier As Object = engine.Operations.Invoke(scope.GetVariable("Bezier"), args)
beziers.Add(bezier)
' 初期化
working = Nothing
End If
Panel1_Paint(Nothing, Nothing)
End Sub
Private Sub Panel1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown
If (Control.ModifierKeys And Keys.Shift) = Keys.Shift Then
' 点の選択
index(0) = focuses(0)
index(1) = focuses(1)
Debug.Print("select!")
End If
End Sub
Private Sub Panel1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove
If (Control.ModifierKeys And Keys.Shift) = Keys.Shift Then
If index(0) = -1 Then
Exit Sub
End If
Dim pnt As Point = Panel1.PointToClient(Cursor.Position)
Dim lst As New IronPython.Runtime.List
lst.Add(pnt.X)
lst.Add(pnt.Y)
Dim tup As New IronPython.Runtime.PythonTuple(lst)
beziers(index(0)).ctrls(index(1)) = tup
Else
For i = 0 To beziers.Count - 1
Dim lst As IronPython.Runtime.List = beziers(i).ctrls
For j = 0 To lst.Count - 1
If IsOvered(New Point(lst(j)(0), lst(j)(1))) Then
focuses(0) = i
focuses(1) = j
Debug.Print("@" & focuses(0) & " " & focuses(1))
End If
Next
Next
End If
Refresh()
'Debug.Print(Cursor.Position.X & " " & Cursor.Position.Y)
End Sub
Private Sub Panel1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseUp
index(0) = -1
index(1) = -1
focuses(0) = -1
focuses(1) = -1
End Sub
Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
Using g As Graphics = Panel1.CreateGraphics
g.Clear(Color.White)
For Each bezier In beziers
' ジェネレータを使って全ての点を取得して描画する
Dim gen As IronPython.Runtime.PythonGenerator = engine.Operations.InvokeMember(bezier, "__iter__")
Dim lst As New List(Of Point)
Try
While True
Dim pnt As IronPython.Runtime.PythonTuple = gen.next
lst.Add(New Point(pnt(0), pnt(1)))
End While
Catch ex As System.InvalidCastException
g.DrawLines(Pens.Black, lst.ToArray)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
If Not CheckBox1.Checked Then
Dim mst As IronPython.Runtime.List = bezier.ctrls
For i = 0 To mst.Count - 1
Dim q As Point = New Point(mst(i)(0), mst(i)(1))
If IsOvered(q) Then
g.FillRectangle(Brushes.Blue, New Rectangle(New Point(q.X - 2, q.Y - 2), New Size(5, 5)))
Else
g.FillRectangle(Brushes.Red, New Rectangle(New Point(q.X - 2, q.Y - 2), New Size(5, 5)))
End If
Next
End If
Next
If Not CheckBox1.Checked Then
If Not (working Is Nothing) Then
For Each p In working
g.FillRectangle(Brushes.Red, New Rectangle(New Point(p.X - 2, p.Y - 2), New Size(5, 5)))
Next
End If
End If
End Using
End Sub
Function IsOvered(ByVal point As Point)
'Debug.Print("isOvered: " & Cursor.Position.X & " " & Cursor.Position.Y & "," & point.X & " " & point.Y)
Dim q As Point = Panel1.PointToClient(Cursor.Position)
Return point.X - 2 <= q.X AndAlso q.X <= point.X + 2 AndAlso point.Y - 2 <= q.Y AndAlso q.Y <= point.Y + 2
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
InitPythonEngine()
End Sub
Sub InitPythonEngine()
engine = Python.CreateEngine()
' サーチパス設定(モジュールのインポートに必要)
engine.SetSearchPaths(New String() {"..\..\IronPython 2.7\Lib", "..\..\PythonLibrary", "."})
' .py読み込み
scope = engine.Runtime.ImportModule("Bezier")
End Sub
Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
Refresh()
End Sub
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment