Hi all,
So I've got my hands on 2013 and am exploring the new Viewpoint functionality within the API. Ultimately, I'm continuing to look at building a custom 3D mouse plugin for Navisworks that can move the camera around in 6DoF. So I'm taking things one step at a time and have code similar to examples I've seen online to:
A) get the current active document
B) get the current active viewpoint from the document
C) create a copy of the current viewpoint
D) modify some aspect of the copy of the current viewpoint (change position, for example)
E) reset the current viewpoint of the current document with the copied viewpoint (containing the new position) using the CopyFrom() method
Of course this works just fine when called as a one-off command within the plugin Execute() method. But ultimately I'd like to package this functionality into a separate thread that runs a continual loop, retreiving data from my device and updating the camera accordingly.
So when I put this code in a separate function, use it to create a thread object, and call start on that thread in Execute(), I get an InvalidOperationException when calling CopyFrom() on the current viewpoint within that thread. I've narrowed it down and know that CopyFrom() is causing the problem but I don't know how to fix it or further debug it. It seems as though there is a problem with modifying the document's current viewpoint from a separate thread that is not the main plugin thread, but why would this be the case? The exception seems to indicate that I'm trying to do an operation on a resource that is closed or not available... possibly, but if this is the case I don't know how to proceed.
I would think this functionality should be available. Has anyone else run into this trying to do modify operations in separate threads? Anything I may be missing?
Thanks,
Hi,
if you have referred to the blogs below, could you provide a small sample project to show the problem? I cannot tell what happened with the the description only.
In adition, did you mean the problem occurs when you running the plugin directly, right?
http://adndevblog.typepad.com/aec/2012/06/navisworks-net-api-2013-new-feature-viewpoint-1.html
http://adndevblog.typepad.com/aec/2012/06/navisworks-net-api-2013-new-feature-viewpoint-2.html
http://adndevblog.typepad.com/aec/2012/06/navisworks-net-api-2013-new-feature-viewpoint-3.html
The simplest case is as follows:
The following code works as you would expect, moving the camera 1 unit in the positive X direction each time you activate the plugin.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Autodesk.Navisworks.Api; using Autodesk.Navisworks.Api.Plugins; using System.Threading; using api = Autodesk.Navisworks.Api; namespace ViewManipPlugin { [PluginAttribute("ViewManipPlugin:ViewManipPlugin", "TME", ToolTip = "ViewManipPlugin by TME", DisplayName = "View Manipulation")] public class ViewManpiPlugin: AddInPlugin { public override int Execute(params string[] parameters) { moveCam(); return 0; } private void moveCam() { Document doc = api.Application.ActiveDocument; Viewpoint curVP = doc.CurrentViewpoint; Viewpoint copyVP = curVP.CreateCopy(); double inc = 1; Point3D pos = new Point3D(copyVP.Position.X + inc, copyVP.Position.Y, copyVP.Position.Z); copyVP.Position = pos; doc.CurrentViewpoint.CopyFrom(copyVP); } } }
Now this code, the only difference being calling the moveCam() function from a thread, produces a System.StackOverflowException at the doc.CurrentViewpoint.CopyFrom(copyVP); line in moveCam().
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Autodesk.Navisworks.Api; using Autodesk.Navisworks.Api.Plugins; using System.Threading; using api = Autodesk.Navisworks.Api; namespace ViewManipPlugin { [PluginAttribute("ViewManipPlugin:ViewManipPlugin", "TME", ToolTip = "ViewManipPlugin by TME", DisplayName = "View Manipulation")] public class ViewManpiPlugin: AddInPlugin { public override int Execute(params string[] parameters) { Thread t = new Thread(this.moveCam); t.Start(); return 0; } private void moveCam() { Document doc = api.Application.ActiveDocument; Viewpoint curVP = doc.CurrentViewpoint; Viewpoint copyVP = curVP.CreateCopy(); double inc = 1; Point3D pos = new Point3D(copyVP.Position.X + inc, copyVP.Position.Y, copyVP.Position.Z); copyVP.Position = pos; doc.CurrentViewpoint.CopyFrom(copyVP); } } }
I'm trying to figure out why this function would produce that exception in a thread.
Hi,
I can reproduce this problem. I think this may because the .NET API is not thread safe, all calls to the Navisworks .NET API should be made on the same thread.
I tested with camera of COM API, it looks working. I have not a conclusion if camera of .NET API can work or not in a thread, however these are what I can see at this moment.
public override int Execute(params string[] parameters) { System.Threading.Thread t = new System.Threading.Thread(this.moveCam); t.Start(); while (!t.IsAlive) ; return 0; } private void moveCam() { //Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument; //Viewpoint curVP = doc.CurrentViewpoint; //Viewpoint copyVP = curVP.CreateCopy(); //double inc = 1; //Point3D pos = new Point3D(copyVP.Position.X + inc, // copyVP.Position.Y, // copyVP.Position.Z); //copyVP.Position = pos; //doc.CurrentViewpoint.CopyFrom(copyVP); ComApi.InwOpState10 state; state = ComBridge.State; ComApi.InwNvViewPoint NvViewPoint = state.CurrentView.ViewPoint; ComApi.InwNvCamera NvCamera = NvViewPoint.Camera; ComApi.InwLPos3f NvCamPos = NvCamera.Position; NvCamPos.SetValue(NvCamPos.data1 + 10, NvCamPos.data2 + 10, NvCamPos.data3); }
Is there a solution for this problem?
I want to do the same, I have an input device and want to use it with Navisworks. I created a RenderPlugin, that manipulates the actual view with CopyViewpointFrom() inside of RenderModel(View view, Graphics graphics).
I don't use threads. The result is the same: It only updates the view if I keep the mouse moving...
Cheers,
Stefan
Can't find what you're looking for? Ask the community or share your knowledge.