Skip to content

Instantly share code, notes, and snippets.

@notionparallax
Created October 7, 2015 07:09
Show Gist options
  • Save notionparallax/154128cb2c7942a100d1 to your computer and use it in GitHub Desktop.
Save notionparallax/154128cb2c7942a100d1 to your computer and use it in GitHub Desktop.
--------------------------------------------------------------------------------------------------------------------------- Class 1
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(int rows, double startValue, ref object matrixTree, ref object Matrix)
{
DataTree<double> mTree = new DataTree<double>();
Matrix matrix = new Matrix(rows, rows);
for(int r = 0; r < rows; r++){
for(int c = 0; c < rows; c++){
if(r == c) { mTree.Add(0, new GH_Path(r)); matrix[r, c] = 0;}
else { mTree.Add(1, new GH_Path(r)); matrix[r, c] = startValue;}
}
}
matrixTree = mTree;
Matrix = matrix;
}
// <Custom additional code>
// </Custom additional code>
}
# ---------------------------------------------------------------------------------------------------------------------- class 2
private void RunScript(DataTree<double> matrixTree, int modRow, int modCol, double newValue, ref object oldValue, ref object mTree, ref object data, ref object modIndex)
{
int rows = matrixTree.BranchCount;
if(modRow >= rows) modRow = rows - 1;
if(modCol >= rows) modCol = rows - 1;
DataTree<double> tmp = matrixTree;
double old = matrixTree.Branch(modRow)[modCol];
if(modRow != modCol){
oldValue = old;
tmp.Branch(modRow).Remove(old);
tmp.Branch(modRow).Insert(modCol, newValue);
data = newValue;
modIndex = (rows * modRow) + modCol;
}
else{
oldValue = "courthouse";
Print("courthouse adjacency matrix");
}
mTree = tmp;
}
// <Custom additional code>
// </Custom additional code>
}
# ---------------------------------------------------------------------------------------------------------------------- class 3
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 parameterNickName, DataTree<double> mTree, double data, int indexPtMod, bool reset, ref object NothingToOutput)
{
// ----------------------------------------------------------------------------------------------------- get input from C#
Grasshopper.Kernel.IGH_Param inputParameter = Component.Params.Input[1]; // find the n1 parameter (i.e. [0]: zero based)
Grasshopper.Kernel.Data.IGH_Structure tree = inputParameter.VolatileData; // get all volatile data provided
Print("Items sampled into IGH_Structure tree: {0}", tree.DataCount);
Grasshopper.Kernel.Parameters.Param_GenericObject currentObject = new Grasshopper.Kernel.Parameters.Param_GenericObject();
currentObject.AddVolatileDataTree(tree);
Print("Volatile data count in currentObject: {0}", currentObject.VolatileDataCount);
// Plan A :------------------------------------------------------------------------------------ via Nickname: find storage
List<Grasshopper.Kernel.Parameters.Param_GenericObject> objects = FindParamObject(parameterNickName);
// Plan B :------------------------------------------------------------ within a group that CONTAINS this C#: find storage
// List<Grasshopper.Kernel.Parameters.Param_GenericObject> objects
// = FindObjectsOfTypeInCurrentGroup<Grasshopper.Kernel.Parameters.Param_GenericObject>();
// --------------------------------------------------------------------- within the group: if storage is empty, create one
Grasshopper.Kernel.Parameters.Param_GenericObject storageObject;
try{storageObject = objects[0]; Print("Note: Getting data from storage");}
catch{storageObject = new Grasshopper.Kernel.Parameters.Param_GenericObject();Print("Note: Creating new storage");}
List<IGH_Goo> dataToSave = new List<IGH_Goo> ();
if (reset)
{
RhinoApp.WriteLine("Reset: geting data from mTree");
List<double> origData = mTree.AllData().ToList();
for (int i = 0; i < origData.Count; i++)
{
dataToSave.Add(new GH_String(String.Format("{0}", origData[i])));
}
}
else{
dataToSave = storageObject.PersistentData.AllData(false).ToList();
// dataToSave = currentObject.VolatileData.AllData(false).ToList(); ------------ too much Vodka: avoid (try Tequila)
dataToSave[indexPtMod] = (IGH_Goo) new GH_Number(data);
}
//Print("persistent data count:{0}", currentObject.PersistentDataCount); ------ maybe avoid Tequila as well (try water)
Print("Data to save count:{0}", dataToSave.Count);
GrasshopperDocument.ScheduleSolution(100, document =>
{
storageObject.PersistentData.ClearData();
storageObject.SetPersistentData(dataToSave);
storageObject.ExpireSolution(false);
});
Print("persistent data count:{0}", storageObject.PersistentDataCount);
}
// <Custom additional code>
private List<Grasshopper.Kernel.Parameters.Param_GenericObject> FindParamObject(string name)
{
return this.owner.OnPingDocument()
.Objects
.OfType<Grasshopper.Kernel.Parameters.Param_GenericObject>()
.Where(obj => obj.NickName.Equals(name))
.ToList();
}
private List<T> FindObjectsOfTypeInCurrentGroup<T>() where T : Grasshopper.Kernel.IGH_DocumentObject
{
List<Grasshopper.Kernel.Special.GH_Group> groups = GrasshopperDocument
.Objects
.OfType<Grasshopper.Kernel.Special.GH_Group>()
.Where(gr => gr.ObjectIDs.Contains(Component.InstanceGuid))
.ToList<Grasshopper.Kernel.Special.GH_Group>();
Print("Objects in group: {0}", groups.Count);
List<T> output = groups.Aggregate(new List<T>(), (list, item) =>
{
list.AddRange(
GrasshopperDocument.Objects.OfType<T>()
.Where(obj => item.ObjectIDs.Contains(obj.InstanceGuid))
);
return list;
}).Distinct().ToList();
return output;
}
// </Custom additional code>
}
# ---------------------------------------------------------------------------------------------------------------------- class4
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(int rows, List<double> MDSList, bool send , ref object mTreeModified, ref object MatrixModified, ref object MatrixToGraph)
{
Matrix adjMatrix = new Matrix(rows, rows);
DataTree <double > tree = new DataTree < double>();
for(int i = 0;i <= rows; i++){
List<double> tmp = MDSList.Skip(i * rows).Take(rows).ToList();
tree.AddRange(tmp, new GH_Path(i));
for(int j = 0;j < tmp.Count;j++){
adjMatrix[i, j] = tmp[j];
}
}
mTreeModified = tree;
MatrixModified = adjMatrix;
if(send)MatrixToGraph = adjMatrix; else MatrixToGraph = null;
}
// <Custom additional code>
// </Custom additional code>
}
# ---------------------------------------------------------------------------------------------------------------------- class5
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(bool enable, System.Object userMatrix, int rows, double minValue, double maxValue, int seed, bool symmetric, int zeroFactor, ref object outMatrix)
{
if(!enable){
Print(" ");
Print("Zzzzzzzzzzzzz");
// --------------------------------------------------------------------------- massacre on text dots (no mercy)
RhinoObject[] objs = RhinoDocument.Objects.FindByObjectType(ObjectType.TextDot);
if (objs != null){
foreach (RhinoObject obj in objs)RhinoDocument.Objects.Delete(obj, true);
}
return;
}
Matrix adjMatrix = (Matrix) userMatrix;
try{
if(adjMatrix.RowCount >= 3) Print("Rows: {0}", adjMatrix.RowCount);
if(!adjMatrix.IsSquare){
Print(" ");
Print("Not square matrix entered: Stopped");
return;
}
}
catch{
Print(" ");
Print("Working on demo rnd Matrix");
adjMatrix = new Matrix(rows, rows);
if(minValue > maxValue) Swap<double>(ref minValue, ref maxValue);
adjMatrix = FillMatrix(adjMatrix, rows, minValue, maxValue, seed, symmetric, zeroFactor);
}
outMatrix = adjMatrix;
}
// <Custom additional code>
public Matrix FillMatrix(Matrix adjM, int rows, double min, double max, int seed, bool symm, int zeroFactor){
int cells = (rows * rows) - rows;
int cellsSymm = cells / 2;
Random rDice = new Random();
int dice;
if(symm){
for(int r = 0;r < rows;r++){
for(int c = r + 1; c < rows;c++){
if(c != r) {
dice = rDice.Next(0, cellsSymm);
if(dice < cellsSymm / zeroFactor) adjM[r, c] = 0;
else adjM[r, c] = rand.NextDouble(min, max);
}
}
}
Matrix tr = adjM.Duplicate(); tr.Transpose(); adjM += tr;
}
else{
for(int r = 0;r < rows;r++){
for(int c = 0; c < rows;c++){
if(c != r){
dice = rDice.Next(0, cells);
if(dice < cells / zeroFactor) adjM[r, c] = 0;
else adjM[r, c] = rand.NextDouble(min, max);
}
}
}
}
return adjM;
}
static bool Swap<T > (ref T x, ref T y)
{
try
{
T t = y;
y = x;
x = t;
return true;
}
catch
{
return false;
}
}
RangedRandom rand = new RangedRandom();
class RangedRandom : System.Random
{
public RangedRandom(): base(){}
public RangedRandom(int seed): base(seed){}
public double NextDouble(double max){
return NextDouble() * max;
}
public double NextDouble(double min, double max){
return (max - min) * NextDouble() + min;
}
}
// </Custom additional code>
}
# ---------------------------------------------------------------------------------------------------------------------- class 6
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(System.Object adjMatrix, double radius, bool showTDots, Color tDotColor, double nodeRadius, double offset, double dotAt, double dotScale, ref object circl, ref object nodeCircles, ref object divPts, ref object connLinesTree)
{
// by The Lord of Darkness due to a Vodka/Tequila starvation situation (please donate some bottles)
if(adjMatrix == null){
Print(" ");
return;
}
else{
Print(" ");
Print("default adjacency matrix");
}
Matrix matrix = (Matrix) adjMatrix; // ---------------------------------------------------- unboxing, that is
int rows = matrix.RowCount;
Circle circle = new Circle(radius);
circl = circle; // >>> out action
Curve cc = circle.ToNurbsCurve();
Point3d[] ccPts;
cc.DivideByCount(rows, true, out ccPts);
divPts = ccPts; // >>> out action
// ------------------------------------------- pts in the row (or column) matrix order: the "nodes" so to speak
List<Point3d> pts = ccPts.ToList();
List<Brep> nodeC = new List<Brep>();
for(int i = 0; i < pts.Count;i++){
Circle cir = new Circle(pts[i], nodeRadius);
nodeC.Add(Brep.CreatePlanarBreps(cir.ToNurbsCurve())[0]);
}
nodeCircles = nodeC;
// ---------------------------------------------- lines as a visual rep of a connection (value NOT zero, that is)
DataTree<Line> connLines = new DataTree<Line>();
DataTree<double> connValues = new DataTree<double>();
for(int r = 0;r < rows;r++){
for(int c = r + 1; c < rows;c++){
if((c != r) && (matrix[r, c] != 0)){
double connValue = matrix[r, c];
Point3d p1 = pts[r]; Point3d p2 = pts[c];
Line connLine = new Line(p1, p2);
// Line connLineSym;
double connValueSymm = matrix[c, r];
if((connValue == connValueSymm) || (connValue == 0) || (connValueSymm == 0)){
connLines.Add(connLine, new GH_Path(r));
connValues.Add(Math.Round(connValue, 2), new GH_Path(r));
}
else{
Print("Double values on Pair: {0},{1}", r, c);
Line[] lines = OffsetLine(connLine, offset);
connLines.Add(lines[0], new GH_Path(r));
connValues.Add(Math.Round(connValue, 2), new GH_Path(r));
connLines.Add(lines[1], new GH_Path(r));
connValues.Add(Math.Round(connValueSymm, 2), new GH_Path(r));
}
}
}
}
connLinesTree = connLines; // >> the action
// ---------------------------------------------------------- the textdots containing the connectivity values
DataTree<TextDot> tdotTree = new DataTree<TextDot>();
List<GH_Path> paths = connLines.Paths.ToList();
for(int i = 0; i < paths.Count;i++){
GH_Path path = paths[i];
for(int j = 0; j < connLines.Branch(path).Count; j++){
Line line = connLines.Branch(path)[j];
double connValue = connValues.Branch(path)[j];
Plane plane = new Plane(line.PointAt(dotAt), Plane.WorldXY.ZAxis);
TextDot tdot = new TextDot(connValue.ToString(), plane.Origin);
// Transform scale = Rhino.Geometry.Transform.Scale(plane.Origin, dotScale);
// tdot.Transform(scale); // ------------------------------------it doesn't work (or I've missed something?)
tdotTree.Add(tdot, new GH_Path(path));
}
}
// --------------------------------------------------------------------------- massacre on text dots (no mercy)
RhinoObject[] objs = RhinoDocument.Objects.FindByObjectType(ObjectType.TextDot);
if (objs != null){
foreach (RhinoObject obj in objs)RhinoDocument.Objects.Delete(obj, true);
}
// ------------------------------------------------------------------------------------------ date another girl
if(showTDots){
List <TextDot> tdotList = tdotTree.AllData().ToList();
Rhino.DocObjects.ObjectAttributes attr = new Rhino.DocObjects.ObjectAttributes();
attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject;
attr.ObjectColor = tDotColor;
for(int i = 0;i < tdotList.Count;i++){
TextDot dot = tdotList[i];
doc.Objects.AddTextDot(dot, attr);
}
}
}
// <Custom additional code>
public Line[] OffsetLine(Line line, double offset){
Curve lineC = line.ToNurbsCurve(); lineC.Domain = new Interval(0, 1);
Plane plane;
lineC.FrameAt(0.5, out plane);
Vector3d v = plane.YAxis; v.Unitize(); v *= offset;
Transform move = Rhino.Geometry.Transform.Translation(v);
Transform moveOther = Rhino.Geometry.Transform.Translation(-v);
Line lineOther = line;
line.Transform(move);
lineOther.Transform(moveOther);
Line[] lines = new Line[2]{line,lineOther};
return lines;
}
// </Custom additional code>
------------------------------------------------------------------------------------------------------------ class 7
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(Line line, double arrowDim, bool flipflop, double sharp, ref object arrowHead)
{
// And I say it again: where's my Vodka?
arrowHead = ArrowHead(line, arrowDim, flipflop, sharp);
}
// <Custom additional code>
public Brep ArrowHead(Line line, double arrowDim, bool flip, double sharp){
Curve lineC = line.ToNurbsCurve(); lineC.Domain = new Interval(0, 1);
double length = lineC.GetLength(0.01);
Point3d p; Point3d pm;
if(flip) {p = lineC.PointAtStart; pm = lineC.PointAtLength(arrowDim);}
else { p = lineC.PointAtEnd;pm = lineC.PointAtLength(length - arrowDim); }
Plane plane; lineC.FrameAt(0.5, out plane);
Vector3d v = plane.YAxis; v.Unitize(); v *= arrowDim / sharp;
Transform moveYpos = Rhino.Geometry.Transform.Translation(v);
Transform moveYneg = Rhino.Geometry.Transform.Translation(-v);
Point3d p1 = pm; Point3d p2 = pm;
p1.Transform(moveYpos); p2.Transform(moveYneg);
Polyline arrowP = new Polyline{p,p1,p2,p};
Brep arrow = Brep.CreatePlanarBreps(arrowP.ToNurbsCurve())[0];
return arrow;
}
// </Custom additional code>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment