Display Pipeline Draw Multiple 3dText Objects

Hey there,

I’m working with a display conduit where I draw multiple text objects using the DisplayPipeline.Draw3dText method. All overloads only accept a single text input which in my case results in several thousands individual calls to the display pipeline. This is slow and bogs down the main thread.

Is there a way to draw all the text at once similar to how we can pass an IEnumerable of Point3d in this method ?

2 Likes

Bumping this thread. Any ideas @nathanletwory, @stevebaer ?

Maybe you can merge all your text into one Mesh object and draw this mesh object…

Hi @mrhe,

Can you provide a simple code sample, that we can run here, that you feel is slow?

Thanks,

– Dale

Sure,

here is a minimal code example:

  private static List<Point3d> _points;

  public static void PostDrawObjects(object sender, Rhino.Display.DrawEventArgs args)
  {
    if (_points == null || _points.Count == 0)
      return;

    foreach (var point in _points)
    {
      var plane = new Plane(point, Vector3d.ZAxis);
      args.Display.Draw3dText(point.X.ToString("0.00"), System.Drawing.Color.Black, plane, 12, "Arial", false, false);
    }
  }

And here it is wrapped in a GH file.
text.gh (7.8 KB)

To keep things simple, I put this logic to the DrawViewportWires override, but in my Rhino plugin the above code resides in DisplayPipeline.PostDrawObjects

Hi @mrhe,

The display performance isn’t horrible - I’m getting about 25 frames/second. But it isn’t great either.

Conduits in RhinoCommon do not cache annotations. They do for Breps and meshes. This is something we can add.

https://mcneel.myjetbrains.com/youtrack/issue/RH-72585

– Dale

2 Likes

Thanks @dale,

it would be awesome if these could be cached, but also if we could pass these as an IEnumerable to avoid multiple calls to the display pipeline. In my application these text objects change quite often hence cache would be invalidated anyway.

Ideally, you’d give us access to the underlying buffer and an option to replace individual text objects.

EDIT: @dale, the link you included in the issue pointing back to this discussion thread is broken. Could you please fix it so that @stevebaer, who is assigned to this issue can find it? Thanks!

We are having this same issue with our plugin, which needs to draw many Text Entities. What I was hoping to do as a workaround is convert the text entities to meshes, and cache those within my plugin. However, I can’t find an efficient way within Rhinocommon to convert a TextEntity to a Mesh. We can go from TextEntity to Brep to Mesh, but this is not efficient. I feel like it must be possible to skip the Brep step. What does Rhino do under the hood to convert an annotation to a mesh when you call DisplayPipeline.DrawAnnotation()?