Question:
I am trying to apply a series of moves with time delay to an object in Navisworks using OverridePermanentTransform and System.Threading.Thread.Sleep(), but Navisworks delays first then applies the moves at the same time.
Solution:
This is similar to the behavior discussed in the other article. The Navisworks screen refresh happens when the UI message loop delivers a paint event. If you have some code running that sits in a loop doing lots of work then there’s no way for the UI message loop to deliver a paint event.
I have practiced the way of Idle event. i.e. put your series of moves in the event. The following codes simulates a transformation: first move the selection along X+ with some distances, next rotate the objects along the axis (origin: center of the bundingbox; vector: 0,0,1). Finally, move the object along Z+ with some distances.
#region HelloWorld
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
//Add two new namespaces
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
namespace BasicPlugIn
{
[PluginAttribute("BasicPlugIn.ABasicPlugin", //Plugin name
"ADSK", //4 character Developer ID or GUID
ToolTip = "BasicPlugIn.ABasicPlugin tool tip",//The tooltip for the item in the ribbon
DisplayName = "Hello World Plugin")] //Display name for the Plugin in the Ribbon
publicclassABasicPlugin : AddInPlugin //Derives from AddInPlugin
{
publicoverrideint Execute(paramsstring[] parameters)
{
Document doc =
Autodesk.Navisworks.Api.Application.MainDocument;
// current selection
ModelItemCollection coll =
doc.CurrentSelection.SelectedItems;
if (coll.Count == 0)
{
MessageBox.Show("no selection!");
return 0;
}
m_Index = 0;
//delagate the event of Idle
Autodesk.Navisworks.Api.Application.Idle +=
newEventHandler<EventArgs>(Idle_EventHandler);
return 0;
}
//simulation index
int m_Index = 0;
//move step
double oMoveStep = 2;
//rotate step
double oRotateStep = 0.1;
void Idle_EventHandler(object sender, EventArgs e)
{
//get handle of Navisworks window
IntPtr hWnd =
Autodesk.Navisworks.Api.Application.Gui.MainWindow.Handle;
if (m_Index < 50)
{
if (m_Index <= 15)
{
// move X+
moveObjAlongX();
}
if (m_Index <= 30 && m_Index > 15)
{
//rotate the axis that (0,0,1) and
//origin is the center of the
//boundingbox of the collection
rotateObjAlongAxis();
}
if (m_Index <= 50 && m_Index > 30)
{
// move Z+
moveObjAlongZ();
}
m_Index++;
}
else
{
//stop the event Idle
Autodesk.Navisworks.Api.Application.Idle -=
Idle_EventHandler;
}
}
#region "transform object"
privatevoid moveObjAlongX()
{
Document doc =
Autodesk.Navisworks.Api.Application.MainDocument;
// current selection
ModelItemCollection coll =
doc.CurrentSelection.SelectedItems;
if (coll.Count == 0)
return;
//build a vector for moving
Vector3D oNewVector3d =
newVector3D(oMoveStep, 0, 0);
//create a transform from a matrix with a vector.
Transform3D oNewOverrideTrans =
Transform3D.CreateTranslation(oNewVector3d);
doc.Models.OverridePermanentTransform(coll,
oNewOverrideTrans,
true);
}
privatevoid rotateObjAlongAxis()
{
Document doc =
Autodesk.Navisworks.Api.Application.MainDocument;
// current selection
ModelItemCollection coll =
doc.CurrentSelection.SelectedItems;
if (coll.Count == 0)
return;
//build the translation from boundingbox center to origin of WCS
Point3D oCenterP =
coll.BoundingBox().Center;
Vector3D oMoveBackToOrig =
newVector3D(-oCenterP.X, -oCenterP.Y, -oCenterP.Z);
Transform3D oMoveBackToOrigM =
Transform3D.CreateTranslation(oMoveBackToOrig);
// set the axis we will rotate around (0,0,1)
UnitVector3D odeltaA =
newUnitVector3D(0, 0, 1);
// Create delta of Quaternion: axis is Z,
Rotation3D delta =
newRotation3D(odeltaA, oRotateStep);
//create a transform from a matrix with a rotation.
Transform3D oNewOverrideTrans =
newTransform3D(delta);
//build final matrix
Transform3D oFinalM =
Transform3D.Multiply(oMoveBackToOrigM, oNewOverrideTrans);
oFinalM =
Transform3D.Multiply(oFinalM, oMoveBackToOrigM.Inverse());
doc.Models.OverridePermanentTransform(coll, oFinalM, true);
}
privatevoid moveObjAlongZ()
{
Document doc =
Autodesk.Navisworks.Api.Application.MainDocument;
// current selection
ModelItemCollection coll =
doc.CurrentSelection.SelectedItems;
if (coll.Count == 0)
return;
//build a vector for moving along X+
Vector3D oNewVector3d =
newVector3D(0,0 ,oMoveStep);
Matrix3 oNewIndentityM =
newMatrix3();
//create a transform from a matrix with a vector.
Transform3D oNewOverrideTrans =
newTransform3D(oNewIndentityM, oNewVector3d);
doc.Models.OverridePermanentTransform(coll,
oNewOverrideTrans,
true);
}
#endregion
}
}
#endregion