I'm developing a Navisworks plugin that tracks the mouse movement to get the elevation of the hovered point and displays it as text at the current mouse location. On click, the elevation text is intended to stick and remain at the clicked location. I'm facing a couple of issues and would appreciate some guidance:
Persistent Markups:
Saved Viewpoints:
This is the class that implements the ToolPlugin
public class ElevationInspectorTool : ToolPlugin
{
private Point3D _pickedPoint;
private int _x;
private int _y;
private bool _isMouseClicked;
private readonly List<Markup> _markups = new List<Markup>();
public void ClearMarkups()
{
_markups.Clear();
}
public override bool MouseMove(View view, KeyModifiers modifiers, int x, int y, double timeOffset)
{
// get current selection
PickItemResult itemResult = view.PickItemFromPoint(x, y);
if (itemResult != null)
{
_pickedPoint = itemResult.Point;
_x = x;
_y = y;
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.Render);
}
return false;
}
public override bool MouseDown(View view, KeyModifiers modifiers, ushort button, int x, int y, double timeOffset)
{
_isMouseClicked = true;
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.Render);
_markups.Add(new Markup()
{
TextFontInfo = new TextFontInfo("typeFace", 20, 10, false, false),
Text = $"Elev :{Math.Round(_pickedPoint.Z, 2)}m",
Location = new Point2D(_x, _y),
OffsetX = 0,
OffsetY = 0,
Color = Color.Green,
ColorAlphaValue = 1.0,
});
return false;
}
public override void OverlayRender(View view, Graphics graphics)
{
if (_pickedPoint != null)
{
if (_isMouseClicked)
{
if (_markups.Count == 1)
{
var savedViewPoint = ViewPointSaver.SaveCurrentView(view.Document, "Test");
view.Document.SavedViewpoints.CurrentSavedViewpoint = savedViewPoint;
}
graphics.BeginWindowContext();
foreach (var markup in _markups)
{
graphics.Color(markup.Color, markup.ColorAlphaValue);
graphics.Text2D(markup.TextFontInfo, markup.Text, markup.Location, markup.OffsetX, markup.OffsetY);
}
graphics.EndWindowContext();
_isMouseClicked = false;
}
else
{
graphics.BeginWindowContext();
foreach (var markup in _markups)
{
graphics.Color(markup.Color, markup.ColorAlphaValue);
graphics.Text2D(markup.TextFontInfo, markup.Text, markup.Location, markup.OffsetX, markup.OffsetY);
}
graphics.Color(Color.Red, 1.0);
graphics.Text2D(new TextFontInfo("typeFace", 20, 10, false, false), $"Elev :{Math.Round(_pickedPoint.Z, 2)}m", new Point2D(_x, _y), 0, 0);
graphics.EndWindowContext();
}
}
}
}
This is the method that saves the view point
public static SavedViewpoint SaveCurrentView(Document document, string name)
{
var existingSavedViewPoint = document.SavedViewpoints.Value.FirstOrDefault(v => v.DisplayName == name);
int count = 1;
string suggestedName = name;
while (existingSavedViewPoint != null)
{
suggestedName = $"{name}-{count:D2}";
existingSavedViewPoint = document.SavedViewpoints.Value.FirstOrDefault(v => v.DisplayName == suggestedName);
count++;
}
SavedViewpoint savedViewPoint = new SavedViewpoint
{
DisplayName = suggestedName
};
document.SavedViewpoints.AddCopy(savedViewPoint);
// after adding the view point retrive it again from the saved view points.
var createdSavedViewPoint = document.SavedViewpoints.Value.First(v => v.DisplayName == savedViewPoint.DisplayName) as SavedViewpoint;
document.SavedViewpoints.ReplaceFromCurrentView(createdSavedViewPoint);
return createdSavedViewPoint = document.SavedViewpoints.Value.First(v => v.DisplayName == savedViewPoint.DisplayName) as SavedViewpoint;
}
Any advice or suggestions on these issues would be greatly appreciated. Thank you!
I'm developing a Navisworks plugin that tracks the mouse movement to get the elevation of the hovered point and displays it as text at the current mouse location. On click, the elevation text is intended to stick and remain at the clicked location. I'm facing a couple of issues and would appreciate some guidance:
Persistent Markups:
Saved Viewpoints:
This is the class that implements the ToolPlugin
public class ElevationInspectorTool : ToolPlugin
{
private Point3D _pickedPoint;
private int _x;
private int _y;
private bool _isMouseClicked;
private readonly List<Markup> _markups = new List<Markup>();
public void ClearMarkups()
{
_markups.Clear();
}
public override bool MouseMove(View view, KeyModifiers modifiers, int x, int y, double timeOffset)
{
// get current selection
PickItemResult itemResult = view.PickItemFromPoint(x, y);
if (itemResult != null)
{
_pickedPoint = itemResult.Point;
_x = x;
_y = y;
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.Render);
}
return false;
}
public override bool MouseDown(View view, KeyModifiers modifiers, ushort button, int x, int y, double timeOffset)
{
_isMouseClicked = true;
Application.ActiveDocument.ActiveView.RequestDelayedRedraw(ViewRedrawRequests.Render);
_markups.Add(new Markup()
{
TextFontInfo = new TextFontInfo("typeFace", 20, 10, false, false),
Text = $"Elev :{Math.Round(_pickedPoint.Z, 2)}m",
Location = new Point2D(_x, _y),
OffsetX = 0,
OffsetY = 0,
Color = Color.Green,
ColorAlphaValue = 1.0,
});
return false;
}
public override void OverlayRender(View view, Graphics graphics)
{
if (_pickedPoint != null)
{
if (_isMouseClicked)
{
if (_markups.Count == 1)
{
var savedViewPoint = ViewPointSaver.SaveCurrentView(view.Document, "Test");
view.Document.SavedViewpoints.CurrentSavedViewpoint = savedViewPoint;
}
graphics.BeginWindowContext();
foreach (var markup in _markups)
{
graphics.Color(markup.Color, markup.ColorAlphaValue);
graphics.Text2D(markup.TextFontInfo, markup.Text, markup.Location, markup.OffsetX, markup.OffsetY);
}
graphics.EndWindowContext();
_isMouseClicked = false;
}
else
{
graphics.BeginWindowContext();
foreach (var markup in _markups)
{
graphics.Color(markup.Color, markup.ColorAlphaValue);
graphics.Text2D(markup.TextFontInfo, markup.Text, markup.Location, markup.OffsetX, markup.OffsetY);
}
graphics.Color(Color.Red, 1.0);
graphics.Text2D(new TextFontInfo("typeFace", 20, 10, false, false), $"Elev :{Math.Round(_pickedPoint.Z, 2)}m", new Point2D(_x, _y), 0, 0);
graphics.EndWindowContext();
}
}
}
}
This is the method that saves the view point
public static SavedViewpoint SaveCurrentView(Document document, string name)
{
var existingSavedViewPoint = document.SavedViewpoints.Value.FirstOrDefault(v => v.DisplayName == name);
int count = 1;
string suggestedName = name;
while (existingSavedViewPoint != null)
{
suggestedName = $"{name}-{count:D2}";
existingSavedViewPoint = document.SavedViewpoints.Value.FirstOrDefault(v => v.DisplayName == suggestedName);
count++;
}
SavedViewpoint savedViewPoint = new SavedViewpoint
{
DisplayName = suggestedName
};
document.SavedViewpoints.AddCopy(savedViewPoint);
// after adding the view point retrive it again from the saved view points.
var createdSavedViewPoint = document.SavedViewpoints.Value.First(v => v.DisplayName == savedViewPoint.DisplayName) as SavedViewpoint;
document.SavedViewpoints.ReplaceFromCurrentView(createdSavedViewPoint);
return createdSavedViewPoint = document.SavedViewpoints.Value.First(v => v.DisplayName == savedViewPoint.DisplayName) as SavedViewpoint;
}
Any advice or suggestions on these issues would be greatly appreciated. Thank you!
Persistent Markups:
Saved Viewpoints:
Persistent Markups:
Saved Viewpoints:
This is exactly what I was trying to do recently: combining an overlay markup and a saved viewpoint.
1. Markup: A customized class. You definitely write your own and handle a list of them.
2. SavedViewpoint: Even though you could save and retrieve SaveViewPoints from nwd file, it is not flexible. Instead, try using GetCamera() and SetCamera(string) method of Viewpoint class. What you are manipulating with these two methods is a simple JSON string, so if you could save your markups as JSON as well, you could write markup and viewpoint info to disk for later usage. Actually I save them to a SQLite db file.
Reference for Viewpoint camera JSON (I didn't write this): https://twentytwo.space/2021/06/02/navisworks-api-viewpoint-part-2/
Here's what I've achieved: when I drop a markup on a model item, the current viewpoint is saved and a thumbnail is generated. By double clicking the thumbnail, I can restore the view.
This is exactly what I was trying to do recently: combining an overlay markup and a saved viewpoint.
1. Markup: A customized class. You definitely write your own and handle a list of them.
2. SavedViewpoint: Even though you could save and retrieve SaveViewPoints from nwd file, it is not flexible. Instead, try using GetCamera() and SetCamera(string) method of Viewpoint class. What you are manipulating with these two methods is a simple JSON string, so if you could save your markups as JSON as well, you could write markup and viewpoint info to disk for later usage. Actually I save them to a SQLite db file.
Reference for Viewpoint camera JSON (I didn't write this): https://twentytwo.space/2021/06/02/navisworks-api-viewpoint-part-2/
Here's what I've achieved: when I drop a markup on a model item, the current viewpoint is saved and a thumbnail is generated. By double clicking the thumbnail, I can restore the view.
Very Nice 👏
Quick questions:
- you say you use SQLite db, are you using the embedded SQLite db associated with each Naviswork ,nwf. I found it very convenient to store small hidden infos for our plugin. No need to link my application with a SQLite library and this db is actually embedded into the .nwf [extracted on open, so can even be viewed/manually edited with an app like "DB Browser for SQLite) and stored back on save I think]
- do you handle updating the snapshots? wondering if these snapshots could be generated dynamically or even replaced with an extra navisworks view??
Very Nice 👏
Quick questions:
- you say you use SQLite db, are you using the embedded SQLite db associated with each Naviswork ,nwf. I found it very convenient to store small hidden infos for our plugin. No need to link my application with a SQLite library and this db is actually embedded into the .nwf [extracted on open, so can even be viewed/manually edited with an app like "DB Browser for SQLite) and stored back on save I think]
- do you handle updating the snapshots? wondering if these snapshots could be generated dynamically or even replaced with an extra navisworks view??
Hi Alexis, regarding your questions:
Since the nwd files in my company are updated frequently, I choose external SQLite files for data storage, so yeah I have to link additional SQLite library. The embedded DB of nwd file is very cool, I even find them amazing, but so far I haven't done any work with it.
The snapshots are generated with the function: Bitmap View.GenerateImage(ImageGenerationStyle style, int width, int height), and by calling Viewpoint.GetCamera() again, a snapshot is updated. I believe the Export Image button on the Viewpoint tab of Navisworks ribbon is using the same View.GenerateImage function.
The Viewpoint.GetCamera() is so convenient that I can, in fact, associate multiple viewpoints with one markup. By "extra Naviswork view", I assume you are talking about something like the Split View on the View tab. I believe it is possible, but it will be way more complicated than handling simple GetCamera JSON string.
Hi Alexis, regarding your questions:
Since the nwd files in my company are updated frequently, I choose external SQLite files for data storage, so yeah I have to link additional SQLite library. The embedded DB of nwd file is very cool, I even find them amazing, but so far I haven't done any work with it.
The snapshots are generated with the function: Bitmap View.GenerateImage(ImageGenerationStyle style, int width, int height), and by calling Viewpoint.GetCamera() again, a snapshot is updated. I believe the Export Image button on the Viewpoint tab of Navisworks ribbon is using the same View.GenerateImage function.
The Viewpoint.GetCamera() is so convenient that I can, in fact, associate multiple viewpoints with one markup. By "extra Naviswork view", I assume you are talking about something like the Split View on the View tab. I believe it is possible, but it will be way more complicated than handling simple GetCamera JSON string.
Can't find what you're looking for? Ask the community or share your knowledge.