Render rhino components in my own WPF rhino plug-in

I’m working on my own rhino plug-in based on WPF.
I want to render rhino components in WPF.
Does any rhino/grasshopper API help me do this? or How can I do this?
Thanks!

human UI did something similar to what I want.
Does anyone know which APIs is used inside human UI? :blush:

Hey @s.wildgold , does this help?

– cs

1 Like

Hi, @csykes Thanks for your reply !
ViewportControl is exactly what I need !
However, it shows the whole picture of the rhino model.
Can I control ViewportControl to show some specific objects automatically?
E.g. pick one curve in rhino and my plug-in’s viewport shows it only.

Hey @s.wildgold,

I’m glad this is helpful, I hope these other thoughts might help us arrive at an answer;

  • You can make an element only show in one specific view (I think)
  • You can control the camera position of the Viewport in the control
  • You could copy your geometry item outside of the bounding box of the current model to isolate it.

In which case, my answer is, I think so. I wrote this badly made method to test this idea. It returns the ID of the geometry item that’s created for the view which’ll need deleting later.

public static Guid ShowMeTheGeometry(Rhino.Display.RhinoView view, GeometryBase geom, Point3d displayAt)
{
	// Put the Geometry where we want it
	GeometryBase focus = geom.Duplicate();
	Point3d center = focus.GetBoundingBox(false).Center;
	Vector3d translation = new Vector3d(displayAt.X - center.X, displayAt.Y - center.Y, displayAt.Z - center.Z);
	focus.Transform(Transform.Translation(translation));

	Rhino.DocObjects.ObjectAttributes oa = new Rhino.DocObjects.ObjectAttributes()
	{
		ViewportId = view.ActiveViewportID
	};
	Guid item = view.Document.Objects.Add(focus, oa);

	// Point the Camera at that object
	BoundingBox bbox = focus.GetBoundingBox(false);
	bbox.Inflate(500);
	view.ActiveViewport.SetCameraTarget(bbox.Center, false);
	view.ActiveViewport.SetCameraLocation(bbox.PointAt(0.5, 0, 0.5), false);


	return item;
}

– cs

1 Like

Hi @s.wildgold,

A good approach might be to use a conduit to control where an object is allowed to be drawn.

For example:

internal class DrawMyStuffConduit : DisplayConduit
{
  /// <summary>
  /// The ID of ViewportControl.Viewport
  /// </summary>
  public Guid ViewportId { get; set; };

  /// <summary>
  /// DisplayConduit.PreDrawObject override
  /// </summary>
  protected override void PreDrawObject(DrawObjectEventArgs args)
  {
    if (null != args && null != args.RhinoObject)
    {
      if (args.Display.Viewport.Id != ViewportId)
        args.DrawObject = false;
    }
    base.PreDrawObject(e);
  }
}

Here, the object will only be drawn in the viewport specified by ViewportId.

– Dale

2 Likes

hi @dale Thanks for your reply.
Could you give me more information about how to combine DisplayConduit with the instance of RhinoWindows.Forms.Controls.ViewportControl?

     if (args.Display.Viewport.Id == ViewportId && args.RhinoObject.IsSelected(false) == 0)
       args.DrawObject = false;

Viewport.Viewport.ZoomExtentsSelected();

Just implement what I want using the code above, though I don’t actually understand the mechanism inside DisplayConduit :sweat: Thanks again @dale :blush:

Setting ViewportId is an impressive approach! Thank you again! Maybe you want to check another answer proposed by @dale

I like dales approach! I use it quite a lot with my plugin, and it’s a very powerful way of displaying geometry :slight_smile: