Refreshing DisplayConduit while in selection/option mode

Hi,

I want to divide an object(for demo purposes I took a curve) and give the user the ability to preview the result by drawing planes at the division points by drawing a custom DisplayConduit. How can I refresh the display conduit everytime a different value is picked until the user is satisfied?

my feeble attempt below:

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        //create test curve
        Line ln = new Line(new Point3d(0, 0, 0), new Point3d(1000, 0, 0));
        doc.Objects.AddLine(ln);
        doc.Views.Redraw();

        //select:
        const ObjectType geometryFilter = ObjectType.Curve;
        int integer = 300;
        OptionInteger optionInteger = new OptionInteger(integer, 200, 900);

        GetObject go = new GetObject();
        go.SetCommandPrompt("Select Beam");
        go.GeometryFilter = geometryFilter;
        go.AddOptionInteger("Segment_Length", ref optionInteger);
        go.GroupSelect = false;
        go.SubObjectSelect = false;
        go.EnableClearObjectsOnEntry(false);
        go.EnableUnselectObjectsOnExit(false);
        go.DeselectAllBeforePostSelect = false;

        for (; ; )
        {
            GetResult res = go.Get();

            if (res == GetResult.Object)
            {
                break;
            }
            else if (res == GetResult.Option)
            {
                //if (go.Object(0).Object().Geometry != null)
                //{
                //    var myConduit = new MyConduit(go.Object(0).Object().Geometry as Curve, optionInteger.CurrentValue)
                //    {
                //        Enabled = true
                //    };
                //}

                continue;
            }
            else if (res != GetResult.Object)
            {
                return Result.Cancel;
            }
        }

        if (go.Object(0).Object().Geometry != null)
        {
            var myConduit = new MyConduit(go.Object(0).Object().Geometry as Curve, optionInteger.CurrentValue) { Enabled = true };
        }

        #endregion
        return Result.Success;
    }
}

class MyConduit : Rhino.Display.DisplayConduit
{
    private Curve Curve { get; set; }
    private int Divider { get; set; }

    public MyConduit(Curve curve, int divider) : base()
    {
        this.Curve = curve;
        this.Divider = divider;
    }

    protected override void PostDrawObjects(DrawEventArgs e)
    {
        base.PostDrawObjects(e);
        e.Display.EnableDepthWriting(false);
        e.Display.EnableDepthTesting(false);
        double[] parameters = this.Curve.DivideByLength(this.Divider, false);

        foreach (double param in parameters)
        {
            Plane pl = new Plane(this.Curve.PointAt(param), Plane.WorldYZ.Normal);
            Rectangle3d rect = new Rectangle3d(pl, new Interval(-200, 200), new Interval(-200, 200));
            e.Display.DrawCurve(rect.ToNurbsCurve(), System.Drawing.Color.MediumVioletRed, 2);
        }
    }
}
  1. You need to create and enable your DisplayConduit before call the GetObject.Get()
  2. If Get() result is GetResult.Option, update the conduit properties (probably with new option value) and call doc.Views.Redraw(). This will cause the call of DisplayConduit.PostDrawObjects() and the opportunity to draw whatever you need to draw.
  3. After exiting the for;; infinite loop, disable the display conduit
    Hope this helps
1 Like

Thank you, I just came around to trying it out now and it worked like intended.

I had to split up the GetObject and GetOption but that’s only for the better I think.