Community
Navisworks API
Welcome to Autodesk’s Navisworks API Forums. Share your knowledge, ask questions, and explore popular Navisworks API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Convert LCS to WCS with COM api

9 REPLIES 9
Reply
Message 1 of 10
mariuroe
3211 Views, 9 Replies

Convert LCS to WCS with COM api

Do anyone know how to convert from LCS to WCS using the Navisworks COM API ?

I have read Xiaodong Liang's article about "Get primitive from solid in Navisworks"; http://adndevblog.typepad.com/aec/2012/05/get-primitive-from-solid-of-navisworks.html, where he explain how to get the primitives. Bu he says that you have to convert from LCS to WCS using GetLocalToWorldMatrix(). I have tried, but can figure out how this works. I'm getting "read only error".

"he 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 4x4 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."

I can't find this GetMatrix() method either? Only a property called Matrix, that is read only. 

9 REPLIES 9
Message 2 of 10
xiaodong_liang
in reply to: mariuroe

Hi,

 

I do not get your problem exactly is, but the following code can get the matrix values. Assume you use C#.

 

     ModelItemCollection oModelColl =
               Autodesk.Navisworks.Api.Application.
                   ActiveDocument.CurrentSelection.SelectedItems;

           //convert to COM selection
           ComApi.InwOpState oState = ComApiBridge.ComApiBridge.State;
           ComApi.InwOpSelection oSel =
                   ComApiBridge.ComApiBridge.ToInwOpSelection(oModelColl);

         
           foreach (ComApi.InwOaPath3 path in oSel.Paths())
           {
               foreach (ComApi.InwOaFragment3 frag in path.Fragments())
               {
                   ComApi.InwLTransform3f3 localToWorld =
 (ComApi.InwLTransform3f3)(object)frag.GetLocalToWorldMatrix(); 
                    Array array_v1 = (Array)(object)localToWorld.Matrix;                 
                    
               }
           }

 

Message 3 of 10
j.gerrets
in reply to: xiaodong_liang

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 from the data in the matrix?

Thanks in advance,

Jeroen

Message 4 of 10
mariuroe
in reply to: xiaodong_liang

Hi!

Sorry for the bad explaination. The problem is the same as Jeroen is asking about. How can I use this array_v1 to get the InwSimpleVertex elements in world coord? 

COMApi.InwOpState oState = ComBridge.State;
COMApi.InwOpSelection oSel = ComBridge.ToInwOpSelection(oModelColl);

CallBackGeomListener callbkListener = new CallBackGeomListener();

foreach (COMApi.InwOaPath3 path in oSel.Paths())
{
   foreach (COMApi.InwOaFragment3 frag in path.Fragments())
   {
        COMApi.InwLTransform3f3 localToWorld = (COMApi.InwLTransform3f3)(object)frag.GetLocalToWorldMatrix();
        Array array_v1 = (Array)(object)localToWorld.Matrix;

 

        // What to do here!?

        frag.GenerateSimplePrimitives(COMApi.nwEVertexProperty.eNORMAL, callbkListener);
    }
}

I tried using the frag.SetLocalToWorldMatrix( .... ), but gets a Navisworks Error "Read only".

 

Message 5 of 10
xiaodong_liang
in reply to: mariuroe

Hi,

 

I think  this may be the frag from path.Fragments() is not a copy. so it is read only. So I tried to make a copy. but the error says Copy has not been implemented. The following is what I tested. I have no idea on this. I logged it #47674: how to use SetLocalToWorldMatrix of InwOaFragment.

 

at this moment, you may have to calculate the WCS by the matrix yourself. It would not be a big difficulty to you, though.

 

    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 = ComApiBridge.ComApiBridge.State;
           ComApi.InwOpSelection oSel =
                   ComApiBridge.ComApiBridge.ToInwOpSelection(oModelColl);

         CallbackGeomListener callbkListener = new CallbackGeomListener(); 
          
           foreach (ComApi.InwOaPath3 path in oSel.Paths())
           {
               foreach (ComApi.InwOaFragment3 frag in path.Fragments())
               {
                   ComApi.InwLTransform3f3 localToWorld =
 (ComApi.InwLTransform3f3)(object)frag.GetLocalToWorldMatrix(); 
                    Array array_v1 = (Array)(object)localToWorld.Matrix;

                    // this line failed. I think it is because the frag from path.Fragments() 
                   // is not a copy. so it is read only.

                   // frag.SetLocalToWorldMatrix(localToWorld, false, false);

                    frag.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, callbkListener);

                   // so I tried to make a copy. but the error says Copy has not been implemented.                  

                    try
                    {
                        ComApi.InwOaFragment3 frag_copy = frag.Copy();


                        frag_copy.SetLocalToWorldMatrix(localToWorld, false, false);
                        frag_copy.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, callbkListener);
                    }
                    catch (Exception ex)
                    {
                    }
                    
               }
           }

         return 0;
      }

 

 

 

Message 6 of 10
mariuroe
in reply to: xiaodong_liang

Thanks!

I have accomplished to do the transform my self. Not in any good way, so it will be great if you figure out about the SetLocalToWorldMatrix method. Please hold me posted 🙂

Message 7 of 10
eric_joe1
in reply to: xiaodong_liang

Hi, I still experience an error message saying below when I use SetLocalToWorldMatrix.

 

Error message:

System.Runtime.InteropServices.COMException was unhandled
  ErrorCode=-2147221504
  HResult=-2147221504
  Message=<<NavisWorks Error - Read only>>
  Source=NavisworksIntegratedAPI.nwOpState.13
  StackTrace:
       at NavisworksIntegratedAPI13.InwOaFragment3.SetLocalToWorldMatrix(InwLTransform3f Matrix, Boolean reverses, Boolean dynamic)
       at ActiveXDumpStructureExample.Form1.generatePrims_Click(Object sender, EventArgs e) in C:\Users\Joe\Documents\Navisworks 2016 Samples\ActiveXDumpStructureExample\Form1.cs:line 143
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at ActiveXDumpStructureExample.Program.Main() in C:\Users\Joe\Documents\Navisworks 2016 Samples\ActiveXDumpStructureExample\Program.cs:line 40
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

1) Where can I find the error report ( #47674: how to use SetLocalToWorldMatrix of InwOaFragment) logged by Xiaodong Liang?

2) If the error above cannot be solved, could you suggest an alternative approach to SetLocalToWorldMatrix?

 

Thank you

 

Message 8 of 10
xiaodong_liang
in reply to: eric_joe1

Hi Joe,

The report for #47674 is logged in our internal database. I checked the comments. Our engineer team said SetLocalToWorldMatrix has been deprecated. The suggestion is same to what I said: we have to transform by the matrix ourselves. Sorry if this is a bad news to you.

so, the alternative is after getting the fragment vertices, transform the coordinates by the matrix of localToWorld.
Message 9 of 10
rickyviking
in reply to: mariuroe

Hi,

 

what is the correct way to apply the whole transformation matrix to the vertices?

 

 

NWComApi.InwLTransform3f3 mLocal2World;
Array array_v1 = (Array)(object)v1.coord;

// how to multiply them to have the vertex in world coords?

Array array_v1_world = ...

Thank you,

Riccardo

 

Message 10 of 10

Is it possible to get the selected Item Name along with the position in the output text file?

@xiaodong_liang 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report