diff --git a/Rhino.Templates/content/CSGrasshopper2/.template.config/dotnetcli.host.json b/Rhino.Templates/content/CSGrasshopper2/.template.config/dotnetcli.host.json
new file mode 100755
index 0000000..e53ed79
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/.template.config/dotnetcli.host.json
@@ -0,0 +1,52 @@
+{
+ "$schema": "http://json.schemastore.org/dotnetcli.host",
+ "symbolInfo": {
+ "IncludeSample": {
+ "longName": "include-sample",
+ "shortName": "sample"
+ },
+ "RhinoVersion": {
+ "longName": "version",
+ "shortName": "v"
+ },
+ "AddonDisplayName": {
+ "longName": "addon-display-name",
+ "shortName": "addon-name"
+ },
+ "ComponentClassName": {
+ "longName": "component-class",
+ "shortName": "component"
+ },
+ "ComponentName": {
+ "longName": "component-name",
+ "shortName": "cname"
+ },
+ "ComponentInfo": {
+ "shortName": "info"
+ },
+ "ComponentChapter": {
+ "longName": "chapter",
+ "shortName": "ch"
+ },
+ "ComponentSection": {
+ "longName": "section",
+ "shortName": "sec"
+ },
+ "UseWpf": {
+ "longName": "include-wpf",
+ "shortName": "wpf"
+ },
+ "UseWinForms": {
+ "longName": "include-winforms",
+ "shortName": "wf"
+ },
+ "BuildYak": {
+ "longName": "build-yak",
+ "shortName": "yak"
+ },
+ "IncludeVSCode": {
+ "longName": "include-vscode-launch",
+ "shortName": "vscode"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/.template.config/ide.host.json b/Rhino.Templates/content/CSGrasshopper2/.template.config/ide.host.json
new file mode 100755
index 0000000..fb277c7
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/.template.config/ide.host.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "http://json.schemastore.org/vs-2017.3.host",
+ "unsupportedHosts": [
+ {
+ "id": "vs"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/.template.config/template.json b/Rhino.Templates/content/CSGrasshopper2/.template.config/template.json
new file mode 100755
index 0000000..c632a76
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/.template.config/template.json
@@ -0,0 +1,157 @@
+{
+ "$schema": "http://json.schemastore.org/template",
+ "author": "McNeel",
+ "classifications": [
+ "Rhino",
+ "Grasshopper2",
+ "GH2"
+ ],
+ "name": "Grasshopper2 PlugIn (WIP)",
+ "description": "Build Grasshopper2 components for Rhino 3D in C#",
+ "identity": "Grasshopper2.Component.CS",
+ "groupIdentity": "Grasshopper2.PlugIn",
+ "precedence": 100,
+ "defaultName": "MyGrasshopper2Components",
+ "shortName": "gh2",
+ "tags": {
+ "language": "C#",
+ "type": "project"
+ },
+ "sourceName": "MyGrasshopper.1",
+ "preferNameDirectory": true,
+ "symbols": {
+ "IncludeSample": {
+ "type": "parameter",
+ "description": "Include code sample.",
+ "dataType": "bool",
+ "defaultValue": "false"
+ },
+ "RhinoVersion": {
+ "type": "parameter",
+ "description": "Version of Rhino",
+ "datatype": "choice",
+ "defaultValue": "8",
+ "choices": [
+ {
+ "choice": "8",
+ "description": "Version 8"
+ }
+ ]
+ },
+ "BuildYak": {
+ "type": "parameter",
+ "description": "Include target to build yak package(s) for your plugin",
+ "datatype": "bool",
+ "defaultValue": "false"
+ },
+ "IncludeVSCode": {
+ "type": "parameter",
+ "description": "Include tasks.json and launch.json to build/debug in VS Code",
+ "datatype": "bool",
+ "defaultValue": "true"
+ },
+ "AddonDisplayName": {
+ "type": "parameter",
+ "description": "Display name of your Grasshopper2 assembly",
+ "datatype": "text",
+ "replaces": "MyGrasshopper.1 Info"
+ },
+ "ComponentClassName": {
+ "type": "parameter",
+ "description": "Name of the component class",
+ "datatype": "text",
+ "replaces": "MyGrasshopper__1Component",
+ "fileRename": "MyGrasshopper__1Component"
+ },
+ "ComponentName": {
+ "type": "parameter",
+ "description": "Display name of the component",
+ "datatype": "text",
+ "replaces": "MyGrasshopper.1 Component"
+ },
+ "ComponentInfo": {
+ "type": "parameter",
+ "description": "Description of the component",
+ "replaces": "ComponentInfo",
+ "defaultValue": "Description of component"
+ },
+ "ComponentChapter": {
+ "type": "parameter",
+ "description": "Chapter of the component",
+ "replaces": "ComponentChapter",
+ "defaultValue": "Chapter"
+ },
+ "ComponentSection": {
+ "type": "parameter",
+ "description": "Section of the component",
+ "replaces": "ComponentSection",
+ "defaultValue": "Section"
+ },
+
+ "UseWpf": {
+ "type": "parameter",
+ "description": "Enable to use WPF (Windows only)",
+ "datatype": "bool",
+ "defaultValue": "false"
+ },
+ "UseWinForms": {
+ "type": "parameter",
+ "description": "Enable the use of Windows Forms",
+ "datatype": "bool",
+ "defaultValue": "false"
+ },
+ "UseWindowsDesktop": {
+ "type": "computed",
+ "value": "UseWpf || UseWinForms"
+ },
+
+ "HostIdentifier": {
+ "type": "bind",
+ "binding": "HostIdentifier"
+ }
+ },
+ "forms": {
+ "JsonStringEncode": {
+ "identifier": "replace",
+ "pattern": "\\\\",
+ "replacement": "\\\\"
+ }
+ },
+ "sources": [
+ {
+ "modifiers": [
+ {
+ "condition": "!IncludeVSCode",
+ "exclude": [ ".vscode/*.*" ]
+ },
+ {
+ "condition": "ComponentClassName == 'MyGrasshopper__1Component'",
+ "rename": {
+ "MyGrasshopper__1Component.cs": "MyGrasshopper.1Component.cs"
+ }
+ }
+ ]
+ }
+ ],
+ "primaryOutputs": [
+ { "path": "MyGrasshopper.1.csproj" },
+ { "path": "MyGrasshopper__1Component.cs" }
+ ],
+ "guids": [
+ "ee4e2b39-d96b-4e4c-8f9d-9b6561e61b64",
+ "e79cd2b5-cb9c-4d08-93ec-446cc1f6d923",
+ "cd826b9b-8dbe-4c31-aac1-6fc7ea2bcfb7"
+ ],
+ "postActions": [
+ {
+ "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")",
+ "description": "Opens the command in the editor",
+ "manualInstructions": [],
+ "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6",
+ "args": {
+ "files": "1"
+ },
+ "continueOnError": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/.vscode/launch.json b/Rhino.Templates/content/CSGrasshopper2/.vscode/launch.json
new file mode 100644
index 0000000..6d3f097
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/.vscode/launch.json
@@ -0,0 +1,47 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Rhino 8 - netcore",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ "program": "",
+ "osx": {
+ "program": "/Applications/Rhino 8.app/Contents/MacOS/Rhinoceros",
+ "args": [
+ "-runscript=_G2"
+ ]
+ },
+ "windows": {
+ "program": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
+ "targetArchitecture": "x86_64",
+ "args": "/netcore /runscript=\"_G2\""
+ },
+ "env": {
+ "RHINO_PACKAGE_DIRS": "${workspaceFolder}/bin/Debug"
+ },
+ "cwd": "${workspaceFolder}",
+ "stopAtEntry": false,
+ "console": "internalConsole"
+ },
+ {
+ "name": "Rhino 8 Windows - netfx",
+ "type": "clr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ "windows": {
+ "program": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
+ "targetArchitecture": "x86_64",
+ "args": "/netfx /runscript=\"_G2\""
+ },
+ "env": {
+ "RHINO_PACKAGE_DIRS": "${workspaceFolder}/bin/Debug"
+ },
+ "cwd": "${workspaceFolder}",
+ "stopAtEntry": false,
+ "console": "internalConsole"
+ },
+ ],
+ "compounds": []
+}
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/.vscode/tasks.json b/Rhino.Templates/content/CSGrasshopper2/.vscode/tasks.json
new file mode 100644
index 0000000..20c5e62
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/.vscode/tasks.json
@@ -0,0 +1,21 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "command": "dotnet",
+ "type": "shell",
+ "args": [
+ "build",
+ "-clp:NoSummary",
+ "${workspaceFolder}/MyGrasshopper.1.csproj"
+ ],
+ "problemMatcher": "$msCompile",
+ "presentation": {
+ "reveal": "always",
+ "clear": true
+ },
+ "group": "build"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Component.3dm b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Component.3dm
new file mode 100644
index 0000000..cf0f299
Binary files /dev/null and b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Component.3dm differ
diff --git a/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Component.ghicon b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Component.ghicon
new file mode 100644
index 0000000..e3f0e3c
Binary files /dev/null and b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Component.ghicon differ
diff --git a/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Plugin.3dm b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Plugin.3dm
new file mode 100644
index 0000000..114cfcf
Binary files /dev/null and b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Plugin.3dm differ
diff --git a/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Plugin.ghicon b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Plugin.ghicon
new file mode 100644
index 0000000..26fcfab
Binary files /dev/null and b/Rhino.Templates/content/CSGrasshopper2/Icons/MyGrasshopper__1Plugin.ghicon differ
diff --git a/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper.1.csproj b/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper.1.csproj
new file mode 100755
index 0000000..928d6f2
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper.1.csproj
@@ -0,0 +1,88 @@
+
+
+
+
+
+ net7.0-windows;net48
+
+ net7.0-windows;net7.0;net48
+
+ net7.0;net48
+
+ true
+ .rhp
+
+ NU1701;NETSDK1086
+
+ NU1701
+
+ true
+
+
+
+
+ 1.0
+ MyGrasshopper.1
+ MyGrasshopper.1 Authors
+ Description of MyGrasshopper.1
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\Program Files\Rhino 8\System\Yak.exe
+ /Applications/Rhino 8.app/Contents/Resources/bin/yak
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper.1PluginInfo.cs b/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper.1PluginInfo.cs
new file mode 100644
index 0000000..970639c
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper.1PluginInfo.cs
@@ -0,0 +1,15 @@
+using System;
+using Grasshopper.UI;
+using Grasshopper.UI.Icon;
+
+namespace MyGrasshopper._1
+{
+ public sealed class MyGrasshopper__1PluginInfo : Grasshopper.Framework.StandardRmaPlugin
+ {
+ public MyGrasshopper__1PluginInfo()
+ : base(new Guid("cd826b9b-8dbe-4c31-aac1-6fc7ea2bcfb7"),
+ new Nomen("MyGrasshopper.1 Info", ""),
+ AbstractIcon.FromResource("MyGrasshopper__1Plugin", typeof(MyGrasshopper__1PluginInfo)))
+ { }
+ }
+}
\ No newline at end of file
diff --git a/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper__1Component.cs b/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper__1Component.cs
new file mode 100644
index 0000000..b6e53de
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/MyGrasshopper__1Component.cs
@@ -0,0 +1,102 @@
+using System;
+using Rhino.Geometry;
+using GrasshopperIO;
+using Grasshopper.UI;
+using Grasshopper.Components;
+
+namespace MyGrasshopper._1
+{
+ [IoId("e79cd2b5-cb9c-4d08-93ec-446cc1f6d923")]
+ public sealed class MyGrasshopper__1Component : Component
+ {
+ public MyGrasshopper__1Component() : base(new Nomen(
+ "MyGrasshopper.1 Component",
+ "ComponentInfo",
+ "ComponentChapter",
+ "ComponentSection"))
+ {
+
+ }
+
+ public MyGrasshopper__1Component(IReader reader) : base(reader) { }
+
+#if IncludeSample
+ ///
+ /// Registers all the input parameters for this component.
+ ///
+ protected override void AddInputs(InputAdder inputs)
+ {
+ inputs.AddPlane("Centre Point", "Cn", "Arc base plane.").Set(Plane.WorldXY);
+ inputs.AddPoint("Start Point", "Pa", "Arc start point.").Set(new Point3d(1, 0, 0));
+ inputs.AddPoint("End Point", "Pb", "Arc end point").Set(new Point3d(-2, 2, 0));
+ }
+
+ ///
+ /// Registers all the output parameters for this component.
+ ///
+ protected override void AddOutputs(OutputAdder outputs)
+ {
+ outputs.AddArc("Clockwise Arc", "Cw", "Arc from start to end, travelling clockwise in the base plane.");
+ outputs.AddArc("Anti-clockwise Arc", "Aw", "Arc from start to end, travelling anti-clockwise in the base plane.");
+ }
+
+ ///
+ /// This is the method that actually does the work.
+ ///
+ /// The IDataAccess object can be used to retrieve data from input parameters and
+ /// to store data in output parameters.
+ protected override void Process(IDataAccess access)
+ {
+ access.GetItem(0, out Plane plane);
+ access.GetItem(1, out Point3d pa);
+ access.GetItem(2, out Point3d pb);
+
+ pa = plane.ClosestPoint(pa);
+ pb = plane.ClosestPoint(pb);
+
+ access.VerifyNonCoincident(plane.Origin, pa, "centre", "start point");
+ access.VerifyNonCoincident(plane.Origin, pb, "centre", "end point");
+
+ var radius = plane.Origin.DistanceTo(pa);
+ var sb = (pb - plane.Origin); sb.Unitize();
+ pb = plane.Origin + sb * radius;
+
+ plane.ClosestParameter(pa, out var ua, out var va);
+ var α = Math.Atan2(va, ua);
+
+ var circle = new Circle(plane, radius);
+ var arc0 = new Arc(pa, -circle.TangentAt(α), pb);
+ var arc1 = new Arc(pa, circle.TangentAt(α), pb);
+
+ access.SetItem(0, arc0);
+ access.SetItem(1, arc1);
+ }
+#else
+ ///
+ /// Registers all the input parameters for this component.
+ ///
+ protected override void AddInputs(InputAdder inputs)
+ {
+
+ }
+
+ ///
+ /// Registers all the output parameters for this component.
+ ///
+ protected override void AddOutputs(OutputAdder outputs)
+ {
+
+ }
+
+ ///
+ /// This is the method that actually does the work.
+ ///
+ /// The IDataAccess object can be used to retrieve data from input parameters and
+ /// to store data in output parameters.
+ protected override void Process(IDataAccess access)
+ {
+
+ }
+#endif
+ }
+}
diff --git a/Rhino.Templates/content/CSGrasshopper2/Properties/launchSettings.json b/Rhino.Templates/content/CSGrasshopper2/Properties/launchSettings.json
new file mode 100644
index 0000000..e30f217
--- /dev/null
+++ b/Rhino.Templates/content/CSGrasshopper2/Properties/launchSettings.json
@@ -0,0 +1,20 @@
+{
+ "profiles": {
+ "Rhino 8 - netcore": {
+ "commandName": "Executable",
+ "executablePath": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
+ "commandLineArgs": "/netcore /runscript=\"_G2\"",
+ "environmentVariables": {
+ "RHINO_PACKAGE_DIRS": "$(ProjectDir)$(OutputPath)\\"
+ }
+ },
+ "Rhino 8 - netfx": {
+ "commandName": "Executable",
+ "executablePath": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
+ "commandLineArgs": "/netfx /runscript=\"_G2\"",
+ "environmentVariables": {
+ "RHINO_PACKAGE_DIRS": "$(ProjectDir)$(OutputPath)\\"
+ }
+ },
+ }
+}
\ No newline at end of file
diff --git a/build/GenerateTemplates.proj b/build/GenerateTemplates.proj
index ac66868..620aab5 100644
--- a/build/GenerateTemplates.proj
+++ b/build/GenerateTemplates.proj
@@ -69,7 +69,7 @@
Condition="!Exists($(MyTextFile))" />
-
+
@@ -200,6 +200,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+