Skip to content

Commit

Permalink
Merge pull request #3 from mishaelnuh/dev
Browse files Browse the repository at this point in the history
Update UI and add annotation
  • Loading branch information
mishaelnuh authored Dec 25, 2019
2 parents f3c9871 + 917d570 commit 8ab2bfe
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 29 deletions.
204 changes: 187 additions & 17 deletions RodSteward/Generator.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.GUI;
using Grasshopper.GUI.Canvas;
using Rhino.Geometry;
using GH_IO.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace RodSteward
{
public class Generator : GH_Component
{
private Model model;
private Model model = new Model();

public bool ForceRecalc = false;
public bool PrintLabel = false;
public bool Collision = false;
public bool AnnotateRods = false;
public bool AnnotateJoints = false;
public bool AnnotateJointArms = false;

public Generator()
: base("Generator", "RSGenerator",
Expand Down Expand Up @@ -54,7 +65,41 @@ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
((IGH_PreviewObject)pManager[2]).Hidden = true;
((IGH_PreviewObject)pManager[3]).Hidden = true;
}

public override bool Write(GH_IWriter writer)
{
try
{
writer.SetBoolean("printlabel", PrintLabel);
writer.SetBoolean("collision", Collision);
writer.SetBoolean("annotaterods", AnnotateRods);
writer.SetBoolean("annotatejoints", AnnotateJoints);
writer.SetBoolean("annotatejointarms", AnnotateJointArms);
}
catch (Exception err)
{
throw err;
}
return base.Write(writer);
}

public override bool Read(GH_IReader reader)
{
try
{
reader.TryGetBoolean("printlabel", ref PrintLabel);
reader.TryGetBoolean("collision", ref Collision);
reader.TryGetBoolean("annotaterods", ref AnnotateRods);
reader.TryGetBoolean("annotatejoints", ref AnnotateJoints);
reader.TryGetBoolean("annotatejointarms", ref AnnotateJointArms);
}
catch (Exception err)
{
throw err;
}
return base.Read(reader);
}

public override void DrawViewportMeshes(IGH_PreviewArgs args)
{
if (model == null)
Expand All @@ -76,6 +121,40 @@ public override void DrawViewportMeshes(IGH_PreviewArgs args)
}
}

public override void DrawViewportWires(IGH_PreviewArgs args)
{
if (model == null)
return;

if (AnnotateRods)
{
foreach (var r in model.RodCentrelines.Values)
{
var midPoint = r.PointAtNormalizedLength(0.5);
var lengthString = String.Format("{0:F2}", r.GetLength());

args.Display.Draw2dText(lengthString, System.Drawing.Color.Blue, midPoint, false, 20, "Lucida Console");
}
}

if (AnnotateJoints)
{
int counter = 0;
foreach(var v in model.Vertices)
{
args.Display.Draw2dText((counter++).ToString(), System.Drawing.Color.Orange, v, false, 20, "Lucida Console");
}
}

if (AnnotateJointArms)
{
foreach (var kvp in model.JointArmLabel)
{
args.Display.Draw2dText(kvp.Key, System.Drawing.Color.Green, kvp.Value, false, 20, "Lucida Console");
}
}
}

protected override void SolveInstance(IGH_DataAccess DA)
{
List<Tuple<int, int>> edges = new List<Tuple<int, int>>();
Expand All @@ -86,29 +165,40 @@ protected override void SolveInstance(IGH_DataAccess DA)
double jointLength = 0;
double tolerance = 0;

model = new Model();

if (!DA.GetDataList(0, edges)) { return; }
if (!DA.GetDataList(1, vertices)) { return; }
if (!DA.GetData(2, ref sides)) { sides = model.Sides; }
if (!DA.GetData(3, ref radius)) { radius = model.Radius; }
if (!DA.GetData(4, ref jointThickness)) { jointThickness = model.JointThickness; }
if (!DA.GetData(5, ref jointLength)) { jointLength = model.JointLength; }
if (!DA.GetData(6, ref tolerance)) { tolerance = model.Tolerance; }
if (!DA.GetData(2, ref sides)) { sides = 50; }
if (!DA.GetData(3, ref radius)) { radius = 6.35; }
if (!DA.GetData(4, ref jointThickness)) { jointThickness = 3.0; }
if (!DA.GetData(5, ref jointLength)) { jointLength = 38; }
if (!DA.GetData(6, ref tolerance)) { tolerance = 0.1; }

if (edges == null || vertices == null) { return; }
if (radius <= 0 || sides <= 2 || jointThickness < 0 || jointLength < 0 || tolerance < 0) { throw new Exception("Invalid input."); }

model.Edges = edges;
model.Vertices = vertices;
model.Sides = (int)Math.Floor(sides);
model.Radius = radius;
model.JointThickness = jointThickness;
model.JointLength = jointLength;
model.Tolerance = tolerance;
if (ForceRecalc || !(model.Edges.SequenceEqual(edges) &&
model.Vertices.SequenceEqual(vertices) &&
model.Sides == (int)Math.Floor(sides) &&
model.Radius == radius &&
model.JointThickness == jointThickness &&
model.JointLength == jointLength &&
model.Tolerance == tolerance))
{
ForceRecalc = false;

model.Edges = edges;
model.Vertices = vertices;
model.Sides = (int)Math.Floor(sides);
model.Radius = radius;
model.JointThickness = jointThickness;
model.JointLength = jointLength;
model.Tolerance = tolerance;

model.Generate(PrintLabel);
}

model.Generate();
model.CalculateClashes();
if (Collision)
model.CalculateClashes();

DA.SetData(0, model);
DA.SetDataTree(1, model.JointMeshTree);
Expand All @@ -129,17 +219,97 @@ public class GeneratorAttribute : Grasshopper.Kernel.Attributes.GH_ComponentAttr
{
public GeneratorAttribute(GH_Component owner) : base(owner) { }

private List<System.Drawing.Rectangle> CapsuleBounds { get; set; }

protected override void Layout()
{
base.Layout();

int numCapsules = 7;
int capsuleHeight = 22;

System.Drawing.Rectangle rec0 = GH_Convert.ToRectangle(Bounds);
rec0.Height += 22 * numCapsules;

CapsuleBounds = new List<System.Drawing.Rectangle>();

for(int i = 0; i < numCapsules; i++)
{
System.Drawing.Rectangle rec = rec0;
rec.Y = rec.Bottom - 22 * (numCapsules - i);
rec.Height = capsuleHeight;
rec.Inflate(0, -2);
CapsuleBounds.Add(rec);
}

Bounds = rec0;
}

protected override void Render(GH_Canvas canvas, System.Drawing.Graphics graphics, GH_CanvasChannel channel)
{
base.Render(canvas, graphics, channel);

if (channel == GH_CanvasChannel.Objects)
{
var component = Owner as Generator;

// Options
var optionTitle = GH_Capsule.CreateTextCapsule(CapsuleBounds[0], CapsuleBounds[0], GH_Palette.Grey, "Options", 0, 1);
graphics.DrawString((component.PrintLabel ? "" : "") + " Print label", optionTitle.Font, System.Drawing.Brushes.Black, CapsuleBounds[1].Location);
graphics.DrawString((component.Collision ? "" : "") + " Collision", optionTitle.Font, System.Drawing.Brushes.Black, CapsuleBounds[2].Location);

optionTitle.Render(graphics, Selected, Owner.Locked, false);
optionTitle.Dispose();

// Annotation
var annotationTitle = GH_Capsule.CreateTextCapsule(CapsuleBounds[3], CapsuleBounds[3], GH_Palette.Grey, "Annotation", 0, 1);
graphics.DrawString((component.AnnotateRods ? "" : "") + " Rods", annotationTitle.Font, System.Drawing.Brushes.Black, CapsuleBounds[4].Location);
graphics.DrawString((component.AnnotateJoints ? "" : "") + " Joints", annotationTitle.Font, System.Drawing.Brushes.Black, CapsuleBounds[5].Location);
graphics.DrawString((component.AnnotateJointArms ? "" : "") + " Joint arms", annotationTitle.Font, System.Drawing.Brushes.Black, CapsuleBounds[6].Location);

annotationTitle.Render(graphics, Selected, Owner.Locked, false);
annotationTitle.Dispose();
}
}
public override GH_ObjectResponse RespondToMouseDown(GH_Canvas sender, GH_CanvasMouseEvent e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
var component = Owner as Generator;

if (((System.Drawing.RectangleF)CapsuleBounds[1]).Contains(e.CanvasLocation))
{
component.PrintLabel = !component.PrintLabel;
component.ForceRecalc = true;
component.ExpireSolution(true);
return GH_ObjectResponse.Handled;
}
else if (((System.Drawing.RectangleF)CapsuleBounds[2]).Contains(e.CanvasLocation))
{
component.Collision = !component.Collision;
component.ExpireSolution(true);
return GH_ObjectResponse.Handled;
}
else if (((System.Drawing.RectangleF)CapsuleBounds[4]).Contains(e.CanvasLocation))
{
component.AnnotateRods = !component.AnnotateRods;
component.ExpireSolution(true);
return GH_ObjectResponse.Handled;
}
else if (((System.Drawing.RectangleF)CapsuleBounds[5]).Contains(e.CanvasLocation))
{
component.AnnotateJoints = !component.AnnotateJoints;
component.ExpireSolution(true);
return GH_ObjectResponse.Handled;
}
else if (((System.Drawing.RectangleF)CapsuleBounds[6]).Contains(e.CanvasLocation))
{
component.AnnotateJointArms = !component.AnnotateJointArms;
component.ExpireSolution(true);
return GH_ObjectResponse.Handled;
}
}

return base.RespondToMouseDown(sender, e);
}
}
Expand Down
38 changes: 26 additions & 12 deletions RodSteward/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public DataTree<Mesh> JointMeshTree {
public List<Tuple<int, int>> ClashedRods { get; set; }
public List<int> ClashedJoints { get; set; }

public Dictionary<string, Point3d> JointArmLabel { get; set; }

public Model()
{
Edges = new List<Tuple<int, int>>();
Expand All @@ -54,13 +56,17 @@ public Model()
JointMeshes = new Dictionary<int, List<Mesh>>();
ClashedRods = new List<Tuple<int, int>>();
ClashedJoints = new List<int>();
JointArmLabel = new Dictionary<string, Point3d>();
}

public void Generate()
public void Generate(bool label = true)
{
ClashedJoints.Clear();
ClashedRods.Clear();

CalculateRodOffsets();
GenerateRodMeshes();
GenerateJointMeshes();
GenerateJointMeshes(label);
}

public Dictionary<Tuple<int, int>, double> CalculateRodOffsets()
Expand Down Expand Up @@ -260,8 +266,11 @@ public Dictionary<Tuple<int, int>, Mesh> GenerateRodMeshes()
return RodMeshes;
}

public Dictionary<int, List<Mesh>> GenerateJointMeshes()
public Dictionary<int, List<Mesh>> GenerateJointMeshes(bool label = true)
{
JointMeshes.Clear();
JointArmLabel.Clear();

var separateJointMeshes = new Dictionary<int, List<Mesh>>();

var jointArmCounter = new Dictionary<int, int>();
Expand Down Expand Up @@ -326,17 +335,20 @@ public Dictionary<int, List<Mesh>> GenerateJointMeshes()
separateJointMeshes[e.Item1].Add(startMesh);
separateJointMeshes[e.Item2].Add(endMesh);

// Create joint label
var startLabel = GenerateJointArmLabel(Vertices[e.Item1], vector, e.Item1.ToString() + ((char)(jointArmCounter[e.Item1] + 64)).ToString(), startCurve.GetLength());
var endLabel = GenerateJointArmLabel(Vertices[e.Item2], vector, e.Item2.ToString() + ((char)(jointArmCounter[e.Item2] + 64)).ToString(), -endCurve.GetLength());
if (label)
{
// Create joint label
var startLabel = GenerateJointArmLabel(Vertices[e.Item1], vector, e.Item1.ToString() + ((char)(jointArmCounter[e.Item1] + 64)).ToString(), startCurve.GetLength());
var endLabel = GenerateJointArmLabel(Vertices[e.Item2], vector, e.Item2.ToString() + ((char)(jointArmCounter[e.Item2] + 64)).ToString(), -endCurve.GetLength());

jointArmCounter[e.Item1]++;
jointArmCounter[e.Item2]++;
jointArmCounter[e.Item1]++;
jointArmCounter[e.Item2]++;

if (startLabel != null)
separateJointMeshes[e.Item1].Add(startLabel);
if (endLabel != null)
separateJointMeshes[e.Item2].Add(endLabel);
if (startLabel != null)
separateJointMeshes[e.Item1].Add(startLabel);
if (endLabel != null)
separateJointMeshes[e.Item2].Add(endLabel);
}
}

foreach (KeyValuePair<int, List<double[]>> kvp in jointCorePoints)
Expand Down Expand Up @@ -489,6 +501,8 @@ private Mesh GenerateJointArmLabel(Point3d origin, Vector3d direction, string la
Point3d planeOrigin = Point3d.Add(origin, startTextOffset);
planeOrigin = Point3d.Add(planeOrigin, dir3 * (pSideMid - origin).Length);

JointArmLabel[label] = planeOrigin;

var plane = new Plane(planeOrigin, dir1, dir2);
plane.UpdateEquation();

Expand Down
Binary file modified examples/Demo.gh
Binary file not shown.

0 comments on commit 8ab2bfe

Please sign in to comment.