Get primitive from solid of Navisworks

By Xiaodong Liang

Geometry is accessed via the COM API: Fragment (InwOaFragment3) object, which you can get via a selection path as below, or through a node object, assuming you have a selection. GenerateSimplePrimitives() requires a class that implements InwSimplePrimitivesCB. You can create a separate class for this or simply implement the interface callback functions in the current class, as below. The geometry primitives are passed into the functions, from which you can access the coordinates.

The coordinates returned from the GenerateSimplePrimitives method are in LCS (local coordinate space), and must be transformed to get them into WCS (world coordinate space). This transform can be accessed via the GetLocalToWorldMatrix() method on the fragment. This returns an InwLTransform3f interface, from which you can use the GetMatrix() method to return a 4×4 matrix as a flat 16-value array. This array is in row-major order. Therefore to get the coordinates into world space, you need to transform them using this matrix.

using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
using ComBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;
using COMApi = Autodesk.Navisworks.Api.Interop.ComApi;
 
#region InwSimplePrimitivesCB Class
class CallbackGeomListener : COMApi.InwSimplePrimitivesCB
{
    public void Line(COMApi.InwSimpleVertex v1,
            COMApi.InwSimpleVertex v2)
    {
        // do your work
    }
 
    public void Point(COMApi.InwSimpleVertex v1)
    {
        // do your work
    }
 
    public void SnapPoint(COMApi.InwSimpleVertex v1)
    {
        // do your work
    }
 
    public void Triangle(COMApi.InwSimpleVertex v1,
            COMApi.InwSimpleVertex v2,
            COMApi.InwSimpleVertex v3)
    {
        // do your work
    }
 
 
 }
 #endregion
 
 #region NW Plugin
[PluginAttribute("Test","ADSK",DisplayName= "Test")]
[AddInPluginAttribute(AddInLocation.AddIn)]
public class Class1:AddInPlugin
{
    public override int Execute(params string[] parameters)
    {
        // get the current selection
        ModelItemCollection oModelColl =
            Autodesk.Navisworks.Api.Application.
                ActiveDocument.CurrentSelection.SelectedItems;
 
        //convert to COM selection
        COMApi.InwOpState oState = ComBridge.State;
        COMApi.InwOpSelection oSel =
                ComBridge.ToInwOpSelection(oModelColl);
 
        // create the callback object
        CallbackGeomListener callbkListener =
                new CallbackGeomListener();
        foreach (COMApi.InwOaPath3 path in oSel.Paths())
        {
            foreach (COMApi.InwOaFragment3 frag in path.Fragments())
            {
                // generate the primitives
                frag.GenerateSimplePrimitives(
                    COMApi.nwEVertexProperty.eNORMAL, 
                                   callbkListener);
            }
        }
 
        return 0;
    }
}
  #endregion

Comments

11 responses to “Get primitive from solid of Navisworks”

  1. Hi
    I’ve tried using this example but can’t then read the InwSimpleVertex values back to usable forms in the Triangle call back. I can see the values in the debugger. but can find no way to convert the values to another float variable.
    Do you have the coe to do that?
    Thanks
    Dave

  2. Xiaodong Avatar
    Xiaodong

    Hi Dave, I wrote a new blog to answer your question. Hope it helps:
    http://adndevblog.typepad.com/aec/2012/05/convert-value-of-inwsimplevertex-to-float-in-c.html
    -Xiaodong

  3. Hi Xiaodong,
    Besides GenerateSimplePrimitives, is there other way to get element’s geometries?
    Using GenerateSimplePrimitives is too slow. So I want to find a quicker way to get geometries.
    Thanks,
    Porter

  4. xiaodong Avatar
    xiaodong

    Hi Porter,
    GenerateSimplePrimitives is the only way.
    Did you dump the primitives for all objects of the model? I’d suggest:
    – dump the specific object per requirement, instead of whole model
    – write an automation to dump primitives for all objects. i.e. set a task scheduler using the automation and run it at night. Thus, you can use the dump data at day time.
    Regards,
    Xiaodong

  5. Hi XiaoDong,
    It is clear that GenerateSimplePrimitives is the only way to get the geometry. My question is, is there a performance difference in using C# via interop or using COM natively via C++? If there is, how much faster is C++? 2x, 5x… ?
    –Chi

  6. Hi XiaoDong,
    Can you please explain how i get the InwSimpleVertex units in World coördinates using the InwLTransform3f created by GetLocalToWorldMatrix?
    Is there a Method that does this or do i have to do this manually?
    Thanks in advance,
    Jeroen

  7. steve Avatar
    steve

    I’m only semi-literate in C++.
    Could you please tell me what the colon is for in this statement
    ‘class CallbackGeomListener : COMApi.InwSimplePrimitivesCB”
    & any relevant info regarding creating a similar statement in VB.net
    thanks

  8. Hi All,
    Here is a quick tip,
    The code below returns the objects in Local Coordinates System.
    GenerateSimplePrimitives(nwEVertexProperty.eNORMAL,callbkListener);
    i.e. every objects is shown at the origin of the project.
    If you need world coordinates you will need to convert the coordinates using.
    ComApi.InwLTransform3f3 localToWorld = (ComApi.InwLTransform3f3)(object)frag.GetLocalToWorldMatrix()
    See this blog post for a full working solution. =)
    https://forums.autodesk.com/t5/navisworks-api/geometry-in-wrong-location-when-accessing-in-api/m-p/5896205/highlight/true

  9. Hello,
    I’m pretty new with API with no experience with programming.
    I need to get geometry dimensions from Navisworks (piping diameter and length) and searching in goolgle I found this topic and I hope you could give a hand. Most of my search results leads me to perform a class library in c# using visual studio. Unfortunatelly my lack of knowledge doesn’t allow me to do it myself.
    I really appreciate if you could give some directions.
    thanks!

  10. Gauhar Nurlybekova Avatar
    Gauhar Nurlybekova

    Hi Gilberto,
    I have a similar problem and I am wondering if you could find a solution?

  11. Hello,
    How to get the matrix of LCS to parent coordinate space.
    What’s the use of ModelItem.Transform? Can I use it to convert vertices to WCS(world coordinate space)?

Leave a Reply

Discover more from Autodesk Developer Blog

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

Continue reading