I saw this post sometime ago about the AddGumball https://wiki.mcneel.com/developer/rhinocommonsamples/gumball
And I have been exploring the Conduit and gumball in Grasshopper to move grasshopper preview points using GumballDisplayConduit. Everything seems to be working fine as I don’t get any errors. but when I select a point and drag it, it does not update the position.
@Dani_Abalde I also saw your post on Gumball for Grasshopper. While you have your example done all in VB, Can you help me here with pointing at what i might be missing in this.
Thanks in advance.
Here is the code
private void RunScript(List<Point3d> pts, bool on, object clear, ref object A)
{
List<Line> outLines = new List<Line>();
if (on)
{
stickyData = ManipulatePoints(pts);
var toggle = this.Component.Params.Input[1].Sources[0];
((GH_BooleanToggle) toggle).Value = false;
toggle.ExpireSolution(true);
}
if (stickyData.Count > 0)
{
if ((bool) clear) stickyData.Clear();
foreach (var i in stickyData.Keys)
pts[i].Transform(stickyData[i]);
}
A = pts;
}
// <Custom additional code>
Dictionary<int, Transform> stickyData = new Dictionary<int, Transform>();
private GumballAppearanceSettings CustomGumballAppearanceSettings()
{
//Return Gumball Appearance Settings with only Translation
var gas = new GumballAppearanceSettings
{
RotateXEnabled = false,
RotateYEnabled = false,
RotateZEnabled = false,
ScaleXEnabled = false,
ScaleYEnabled = false,
ScaleZEnabled = false,
TranslateXEnabled = true,
TranslateXYEnabled = true,
TranslateYEnabled = true,
TranslateYZEnabled = true,
TranslateZEnabled = true,
TranslateZXEnabled = true,
MenuEnabled = false,
RelocateEnabled = false
};
return gas;
}
class CustomGetTransform : GetTransform
{
public GumballDisplayConduit lineDc;
private readonly List<Point3d> ptsToSelectFrom;
public int currentSelIndex;
public readonly Dictionary<int, Transform> info;
public CustomGetTransform(GumballDisplayConduit inLineDc, List<Point3d> inPtsToSelectFrom)
{
lineDc = inLineDc;
ptsToSelectFrom = inPtsToSelectFrom;
currentSelIndex = -1;
info = new Dictionary<int, Transform>();
}
public override Transform CalculateTransform(RhinoViewport viewport, Point3d point)
{
// do we want this first line??
//if (lineDc.InRelocate) return lineDc.PreTransform;
return lineDc.TotalTransform;
}
protected override void OnMouseDown(GetPointMouseEventArgs e)
{
//initial mouse down event
if (lineDc.PickResult.Mode != GumballMode.None)
return;
lineDc.PickResult.SetToDefault();
var picker = new PickContext
{
View = e.Viewport.ParentView,
PickStyle = PickStyle.PointPick
};
var xform = e.Viewport.GetPickTransform(e.WindowPoint);
picker.SetPickTransform(xform);
//Point Selection
for (int i = 0; i < ptsToSelectFrom.Count; i++)
{
double depth;
double distance;
if (picker.PickFrustumTest(ptsToSelectFrom[i], out depth, out distance))
{
currentSelIndex = i;
if (!info.ContainsKey(i))
info.Add(i, Transform.Identity);
break;
}
}
//Gumball
Line pickLine;
e.Viewport.GetFrustumLine(e.WindowPoint.X, e.WindowPoint.Y, out pickLine);
picker.PickLine = pickLine;
picker.UpdateClippingPlanes();
lineDc.PickGumball(picker, this);
}
private void updateSelectedPoint(Transform xform)
{
//Update the Selected Point and info Dictionary
var pt = ptsToSelectFrom[currentSelIndex];
pt.Transform(xform);
info[currentSelIndex] *= xform;
}
protected override void OnMouseMove(GetPointMouseEventArgs e)
{
//Update the Gumball in the Display Conduit
if (lineDc.PickResult.Mode == GumballMode.None) return;
//lineDc.CheckShiftAndControlKeys();
Line worldLine;
var res = e.Viewport.GetFrustumLine(e.WindowPoint.X, e.WindowPoint.Y, out worldLine);
if (!res)
worldLine = Line.Unset;
var rc = lineDc.UpdateGumball(e.Point, worldLine);
if (rc)
base.OnMouseMove(e);
}
public GetResult MoveGumball()
{
// Get point on a MouseUp event
if (lineDc.PreTransform != Transform.Identity)
{
HaveTransform = true;
Transform = lineDc.PreTransform;
}
SetBasePoint(lineDc.BaseGumball.Frame.Plane.Origin, false);
// V5 uses a display conduit to provide display feedback
// so shaded objects move
//ObjectList.DisplayFeedbackEnabled = true;
if (this.Transform != Transform.Identity)
{
//ObjectList.UpdateDisplayFeedbackTransform(Transform);
updateSelectedPoint(this.Transform);
}
// Call Get with mouseUp set to true
var rc = this.Get(true);
// V5 uses a display conduit to provide display feedback
// so shaded objects move
//ObjectList.DisplayFeedbackEnabled = false;
return rc;
}
protected override void OnDynamicDraw(GetPointDrawEventArgs e)
{
foreach (var i in info.Keys)
e.Display.DrawPoint(ptsToSelectFrom[i], PointStyle.X, 5, System.Drawing.Color.Green);
}
}
private Dictionary<int, Transform> ManipulatePoints(List<Point3d> ptsToSelectFrom)
{
var conduit = new GumballDisplayConduit();
var baseGumball = new GumballObject();
var cgt = new CustomGetTransform(conduit, ptsToSelectFrom);
cgt.SetCursor(CursorStyle.Default);
cgt.lineDc.Enabled = true;
while (true)
{
if (cgt.currentSelIndex >= 0)
{
var currentSelPt = ptsToSelectFrom[cgt.currentSelIndex];
if (conduit.PickResult.Mode == GumballMode.None)
baseGumball.SetFromPlane(new Plane(currentSelPt, Vector3d.ZAxis));
conduit.SetBaseGumball(baseGumball, CustomGumballAppearanceSettings());
conduit.Enabled = true;
cgt.lineDc = conduit;
cgt.SetCommandPrompt("Drag gumball or select another point. (<ESC> to exit)");
cgt.MoveGumball();
conduit.Enabled = false;
}
else
{
cgt.SetCommandPrompt("Select grasshopper points. (<ESC> to exit)");
cgt.Get(true);
}
RhinoDoc.ActiveDoc.Views.Redraw();
if (cgt.CommandResult() != Result.Success)
{
cgt.lineDc.Enabled = false;
return cgt.info;
}
if (cgt.Result() == GetResult.Point)
{
// update base gumball
var gbFrame = conduit.Gumball.Frame;
var baseFrame = baseGumball.Frame;
baseFrame.Plane = gbFrame.Plane;
baseGumball.Frame = baseFrame;
}
}
}
Here is the preview of viewport
Also the GH file is attached. GH_GumballTest.gh (10.1 KB)