Draw Text Graphics

By Xiaodong Liang

I do not see Navisworks 2015 API has not yet exposed the ability to draw text with Renderplugin and ToolPlugin. This reminds me of the workaround I shared with my colleague Miro in consulting team early this year.

We can draw the text ourselves. The challenge is to get the strokes of the text. Fortunately, Windows API provides something: FormattedText, PathGeometry etc , by which, I drew the text as below. Not too bad, isn’t it? 

CustomText

By different Font (typeface), the strokes would be much different. So to have the simplest scenario, I use TXT in which most strokes are polyline only (at least for the alphanumeric and some basic letters). If using other Font, you will have to handle the scenarios of arc, even poly bezier etc.

There will be more works ahead, to make the text appearing nicely according to your requirement, but this demo could be a start. Of course, if API exposes text graphics, that will be much nicer.

  


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Media;
using System.Globalization;
using System.Windows;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
namespace navisdrawtext {
//tool plugin which draws custom text
[Plugin("ToolPluginCustomText", "ADSK")]
public class ToolPluginTest: ToolPlugin
{
ModelItem clickedModel = null;
int mouse_click_x;
int mouse_click_y;
public override bool MouseDown(View view,
KeyModifiers modifiers,
ushort button,
int x,
int y,
double timeOffset)
{
// get current selection
PickItemResult itemResult =
view.PickItemFromPoint(x, y);
if (itemResult != null)
{
clickedModel =
itemResult.ModelItem;
Autodesk.Navisworks.Api.Application.ActiveDocument.ActiveView.
RequestDelayedRedraw(ViewRedrawRequests.Render);
mouse_click_x = x;
mouse_click_y = y;
}
return false;
}
//2014:
//public override void OverlayRenderWindow(View view, Autodesk.Navisworks.Api.Graphics graphics)
//2015 :
public override void OverlayRender(View view, Autodesk.Navisworks.Api.Graphics graphics)
{
if (clickedModel != null)
{
//red color
graphics.Color(Autodesk.Navisworks.Api.Color.Red, 0.7);
// Create the formatted text based on the properties set.
FormattedText formattedText = new FormattedText(
"Hello 12345678 :-)",
CultureInfo.GetCultureInfo("en-us"),
System.Windows.FlowDirection.LeftToRight,
new Typeface("Txt"), 30,
System.Windows.Media.Brushes.Black
);
Geometry geo = formattedText.BuildGeometry(new System.Windows.Point(mouse_click_x, mouse_click_y));
PathGeometry pathgeo = geo.GetOutlinedPathGeometry();
PathFigureCollection pathfigcoll = pathgeo.Figures;
//draw the text with the paths one by one, simply connecting the points by line.
//please search more elegant ways on internet.
foreach(PathFigure pathfig in pathfigcoll)
{
foreach(PathSegment seg in pathfig.Segments)
{
if (seg is LineSegment)
{
LineSegment lineseg = seg as LineSegment;
} else if (seg is PolyLineSegment)
{
PolyLineSegment polyline = seg as PolyLineSegment;
for (int i = 0; i < polyline.Points.Count - 1; i++)
{
int base_y = mouse_click_y;
double actual_y_1 = 2 * base_y - polyline.Points[i].Y;
double actual_y_2 = 2 * base_y - polyline.Points[i + 1].Y;
graphics.Line(new Point2D(polyline.Points[i].X, actual_y_1),
new Point2D(polyline.Points[i + 1].X, actual_y_2));
}
} else if (seg is PolyBezierSegment)
{
PolyBezierSegment polyBseg = seg as PolyBezierSegment;
for (int i = 0; i < polyBseg.Points.Count - 1; i++)
{
int base_y = mouse_click_y;
double actual_y_1 = 2 * base_y - polyBseg.Points[i].Y;
double actual_y_2 = 2 * base_y - polyBseg.Points[i + 1].Y;
graphics.Line(new Point2D(polyBseg.Points[i].X, actual_y_1),
new Point2D(polyBseg.Points[i + 1].X, actual_y_2));
}
}
}
}
}
}
}
// plugin that enables tool plugin
[Plugin("EnableToolPluginCustomText", "ADSK",
DisplayName = "EnableToolPluginCustomText")]
public class EnableToolPluginExample: AddInPlugin
{
static bool enable = false;
public override int Execute(params string[] parameters)
{
if (enable)
{
//switch to the native tool
Autodesk.Navisworks.Api.Application.MainDocument.Tool.Value = Tool.Select;
} else
{
//switch to custom tool
ToolPluginRecord toolPluginRecord =
(ToolPluginRecord) Autodesk.Navisworks.Api.Application.Plugins.FindPlugin(
"ToolPluginCustomText.ADSK");
Autodesk.Navisworks.Api.Application.MainDocument.Tool.
SetCustomToolPlugin(toolPluginRecord.LoadPlugin());
}
enable = !enable;
return 0;
}
}
}

Comments

One response to “Draw Text Graphics”

  1. Ulrik Dan Christensen Avatar
    Ulrik Dan Christensen

    hi Xiaodong Liang,
    Interesting article. We wanted to do the same thing and ended up using Navisworks build-in links labels with “in 3D” and icon type as text in the options menu. That will give you a even nicer 3d label with text. In the advanced menu you can change the font too
    Ulrik

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading