Grasshopper requirements for Twikit Connect
Introduction
With Twikit Connect, a designer has the ability to expand the possibilities for product parametrization. As well as using the Twikit modifiers, one can also use Grasshopper's power to its advantage.
Designing for Twikit Create in Grasshopper does have some rules linked to it to ensure optimal compatibility. In this document, all the guidelines will be explained for a smooth integration in Twikit Create.
The use of in- and outputs
When connecting Grasshopper with Twikit Create, in- and outputs are needed to set up communication between the two. Twikit Connect supports a wide range of in- and outputs as long as they are configured properly. Everything should be configured the same, except for the mesh parameter, which is an exception to the rule.
Twikit Connect will, regardless of what is configured before, overwrite the input parameters with what comes from Twikit Create. So if a slider is for example connected to a number input param, the slider can be used for testing in Rhino/Grasshopper while designing, but once imported in Twikit Create, the value of the slider will play no further role as the number that gets input from Twikit Create, will overwrite this value.
Basic configuration
In order to expose an in- or output to Twikit Connect, the parameter of the corresponding item should be put in its own group with the name “RH_IN: [Unique name]” or “RH_OUT: [Unique name]” depending on if it is an in- or output.
Mesh configuration
For meshes, a slightly different configuration is needed, especially for the input. It is driven by a text param and then converted into a C# modifier. While designing, it is advised to use the normal mesh param and switch just before exporting the script for implementation in Twikit Create. For the output, the only difference is the name of the group: “RH_OUT:mesh: [Unique name]”.
A mesh output should always be one joined, manifold mesh.
The code that should be put inside of the C# script:
using System;
using System.Collections;
using System.Collections.Generic;
using Rhino;
using Rhino.Geometry;
using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using System.IO;
using System.Linq;
/// <summary>
/// This class will be instantiated on demand by the Script component.
/// </summary>
public class Script_Instance : GH_ScriptInstance
{
#region Utility functions
/// <summary>Print a String to the [Out] Parameter of the Script component.</summary>
/// <param name="text">String to print.</param>
private void Print(string text) { /* Implementation hidden. */ }
/// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
/// <param name="format">String format.</param>
/// <param name="args">Formatting parameters.</param>
private void Print(string format, params object[] args) { /* Implementation hidden. */ }
/// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
/// <param name="obj">Object instance to parse.</param>
private void Reflect(object obj) { /* Implementation hidden. */ }
/// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
/// <param name="obj">Object instance to parse.</param>
private void Reflect(object obj, string method_name) { /* Implementation hidden. */ }
#endregion
#region Members
/// <summary>Gets the current Rhino document.</summary>
private readonly RhinoDoc RhinoDocument;
/// <summary>Gets the Grasshopper document that owns this script.</summary>
private readonly GH_Document GrasshopperDocument;
/// <summary>Gets the Grasshopper script component that owns this script.</summary>
private readonly IGH_Component Component;
/// <summary>
/// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0.
/// Any subsequent call within the same solution will increment the Iteration count.
/// </summary>
private readonly int Iteration;
#endregion
/// <summary>
/// This procedure contains the user code. Input parameters are provided as regular arguments,
/// Output parameters as ref arguments. You don't have to assign output parameters,
/// they will have a default value.
/// </summary>
private void RunScript(string x, ref object A)
{
var decodedData = Convert.FromBase64String(x); //the obj file
var filename = Path.GetTempFileName();
filename = Path.ChangeExtension(filename, ".obj"); // the tmp obj file name on disk
File.WriteAllBytes(filename, decodedData); //write the file to disk
var doc = Rhino.RhinoDoc.CreateHeadless(null); // create a Rhino File
doc.Import(filename); // import the obj into this file
var objects = doc.Objects.GetObjectList(Rhino.DocObjects.ObjectType.Mesh); // get the imported meshes
Mesh geometry = objects.SingleOrDefault().Geometry as Mesh; // get the mesh
A = geometry; // return the mesh
}
// <Custom additional code>
// </Custom additional code>
}
Best practices
In Grasshopper, one has an infinite amount of possibilities to get the same result. In this section, a few best practices are bundled that have been proven to work well with Twikit Create.
Clean file
By having a clean file, unwanted surprises should be kept to a minimum. It will also keep debugging time to a minimum as the file is easier to understand.
Keeping the file clean means:
No modifiers that are not in use (stray modifiers).
These might lead to errors or warnings which leads to the script not being compatible.Internalise all data that is otherwise linked to objects in Rhino.
Not internalising this data will lead to the loss of the data when saving the Grasshopper file.Group inputs and outputs.
Having all input parameters together at the beginning of the script and all outputs together on the right side of the script will contribute to the readability of the script.Working from left to right.
Most people read from left to right. If this is incorporated into the script, it will again be much easier to debug it if needed.
Data Dams
Data dams can be very useful when working on the script, it stops data from flowing through the modifier unless it is opened. This will avoid the script recomputing fully when making a change at the beginning of the script.
With Twikit Connect, the script should fully recompute when one of its parameters change. Thus all data dams should be set to Always open before importing the script to Twikit Create.
Fast and full versions
A full grasshopper script might take a minute or more to recalculate fully. Having this reflect in the configurator is far from ideal. This is why it is advised to have a light or fast version of the script, where a simple representation is shown of the product. This could for example be a flat brace, without ribs, clips for closing or other details. This fast script should take 0-10 seconds to fully recalculate to have an acceptable user experience when implemented in the configurator.
The full script is then shown at the end of the configurator when everything is configured. This script will be a lot heavier but will show what the end product will look like.
If the full script is still too slow for a proper user experience, a differentiation can be made between a full visualization script and a full export script. The Full visualizations script will then be used for visualizing in the last step and the full export script will be used for exporting in the back-end after a configuration is saved and ordered.
Keep in mind that having more versions of one file (Fast, Full & Export) needs a good overview so all changes are always implemented in all applicable versions of said file.
Adding functional points
When multiple points are needed from TwikFit, it is advised to use one single point param that captures the whole list of points. In the example below, the “RH_IN: LOP” captures all points, the Partition List param divides the list into groups and the Explode Tree separates those groups into branches.
The use of Grasshopper plugins
One of the powers of Grasshopper lies in the numerous available plugins. Whether it is for calculating complex lattices or remeshing an object according to a specific algorithm, there is a plugin for that.
It’s not all sunshine and rainbows though, while Twikit Connect supports a lot of plugins for Grasshopper already, they are not all supported. If a certain plugin is not found in the list of supported or unsupported plugins, one can always reach out to Twikit to check compatibility. If a plugin is in the unsupported list, it means it cannot be supported, either due to incompatibility or legal reasons.
Checking the plugins used
When designing in Grasshopper, it is not always easy to keep an overview of all the plugins used in a script. This can luckily, easily be checked with another plugin called MetaHopper. By using its Document Info component, The A param or “3rd Party Assemblies (A) as a list” will output all 3rd party plugins that can be found in the document (excluding the Document Info component itself).
Don’t forget to delete the component for checking the plugins before importing the script in Twikit Create.
Supported plugins
Name | Version | URL | Comments |
---|---|---|---|
4D Noise | 1.0.0.0 |
| |
Caterpillar | 1.2.0 |
| |
Clipper | 0.3.2.0 | https://www.food4rhino.com/en/app/clipper-grasshopper-and-rhino |
|
Crystallon | 2.0 | Components Only | |
CurveOffsetTools | 1.0.0.0 |
|
|
Dendro | 0.9.0.0 |
| |
Engrave | 1.2.0.0 |
|
|
Exoskeleton 2 | 1.0.0.0 |
| |
Fattener | 0.0.0.1 | https://discourse.mcneel.com/t/skeleton-fattener-mesh-cage-morph/74766 |
|
GENERATION | 1.0.0.0 |
| |
BIM GeoGym IFC | 1.9.4.0 | Alias: ggRhinoIFC | |
Heteroptera | 0.6.2.4 |
| |
Human | 1.2.0 |
| |
Jackalope | 1.0.0.3 |
| |
jSwan | 1.2.0 |
| |
Kangaroo 2 | 2.5.3 |
| |
LunchBox | 2020.11.2.0 |
| |
LunchBoxML | 2020.10.13.0 | Included in LunchBox installer | |
MarchingCubes | 1.0.0.0 |
|
|
Mesh+ | 2.1.03 | Components Only | |
Mesh Pipe | 1.0.0.0 |
| |
OpenNest | 1.3.3 |
| |
Plankton | 0.3.0.0 |
| |
Python Interpreter | 0.6.0.3 | ||
Pufferfish | 3.0.0.0 |
| |
Room Surveyor | 0.7.0.1 |
| |
Rooster | 1.1.0 | Alias: GhPotrace | |
Shortest Walk | 1.5.1.0 |
| |
Weaverbird | 0.9.0.1 |
| |
XtreeE | 1.0 |
|
|
Unsupported plugins
Name | Url | Reason |
---|---|---|
MeshEdit | No commercial license |