I managed to get the C++ code converted to VB, but I am lost from there.
Imports Microsoft.VisualBasic
'Get CoordinationModel
Private Sub test5()
#pragma region Retrieve NWD Model from BlockTable
Dim entId As AcDbObjectId
Dim blockEnts As AcDbObjectIdArray
AcDbBlockTable* blkTbl
AcDbDatabase* db = acdbHostApplicationServices()-> workingDatabase()
If Not eOkVerify(db-> getSymbolTable(blkTbl, AcDb:=:=kForRead)) Then
Return
End If
' open named block and get NWD model
AcDbBlockTableRecord* blkRec
AcDbBlockTableRecordIterator* iter
If Not eOkVerify(blkTbl-> getAt(ACDB_MODEL_SPACE, blkRec, AcDb:=:=kForRead)) Then
Return
End If
If Not eOkVerify(blkRec-> newIterator(iter, True, True)) Then
blkRec-> close()
Return
End If
Do While (Not iter)-> done()
Acad.ErrorStatus es = iter-> getEntityId(entId)
If es = Acad.eOk Then
blockEnts.append(entId)
End If
iter-> [step](True, True)
Loop
blkRec-> close()
Dim iter As delete
blkTbl-> close()
#pragma endregion
#pragma region Get entityname from ObjectId
'test drawing has only one NWD and it would be the first one
Dim ent_name As ads_name
If Not eOkVerify(acdbGetAdsName(ent_name, blockEnts(0))) Then
Return
End If
#pragma endregion
'Get Resbuf struct of DXF Data of Selected Model
resbuf* args = acutNewRb(RTSTR)
acutNewString(_T("*"), args-> resval.rstring)
resbuf* entdata = acdbEntGetX(ent_name, args)
acutRelRb(args)
LoopRbChain(entdata)
acutRelRb(entdata)
'Get File Path
acutPrintf(_T("NWD file path is %s"), nwdData.filePath)
'Create a transform Matrix to get Scale\Insertion\Rotation angle
Dim mat As AcGeMatrix3d
Dim size As Integer = nwdData.rreals.length()
For i As Integer = 0 To 3
For j As Integer = 0 To 3
mat(i,j) = nwdData.rreals.at(4*i + j)
Next j
Next i
Dim scale As Double = mat.scale()
Dim insertionV As AcGeVector3d = mat.translation()
AcGePoint3d insertionPt(insertionV.x, insertionV.y, insertionV.z)
'Some Math to get rotation angle from Matrix
'Converter Note: VB cannot determine whether both operands of this division are integer types - if they are then you should use the VB integer division operator:
Dim acosVal As Double = mat(0, 0) / scale
If acosVal > 1.0 Then
acosVal = 1.0
ElseIf acosVal < -1.0 Then
acosVal = -1.0
End If
Dim rotAngle As Double = acos(acosVal)
ASSERT(0.0 <= rotAngle AndAlso rotAngle <= M_PI)
If mat(0, 1) > 0.0 Then
rotAngle = 2.0 * M_PI - rotAngle
End If
acutPrintf(_T(vbLf & " Insertion Point [%.2f,%.2f,%.2f]," & vbLf & " Scale = %.2f " & vbLf & " Rotation = %.2f"), insertionV.x, insertionV.y, insertionV.z, scale, (rotAngle*180)/M_PI)
End Sub
Friend Structure NWDData
Private filePath As CString
Private rreals As AcArray
End Structure
'Global Declration
Private nwdData As NWDData
'Helper Methods
Private Function dxfCodeToDataType(ByVal resType As Integer) As Integer
' which data type is this value
If (resType >= 0) AndAlso (resType <= 9) Then
Return RTSTR
ElseIf (resType >= 10) AndAlso (resType <= 17) Then
Return RT3DPOINT
ElseIf (resType >= 38) AndAlso (resType <= 59) Then
Return RTREAL
ElseIf (resType >= 60) AndAlso (resType <= 79) Then
Return RTSHORT
ElseIf (resType >= 90) AndAlso (resType <= 99) Then
Return RTLONG
ElseIf (resType = 100) OrElse (resType = 101) OrElse (resType = 102) OrElse (resType = 105) Then
Return RTSTR
ElseIf (resType >= 110) AndAlso (resType <= 119) Then
Return RT3DPOINT
ElseIf (resType >= 140) AndAlso (resType <= 149) Then
Return RTREAL
ElseIf (resType >= 170) AndAlso (resType <= 179) Then
Return RTSHORT
ElseIf (resType >= 210) AndAlso (resType <= 219) Then
Return RT3DPOINT
ElseIf (resType >= 270) AndAlso (resType <= 299) Then
Return RTSHORT
ElseIf (resType >= 300) AndAlso (resType <= 309) Then
Return RTSTR
ElseIf (resType >= 310) AndAlso (resType <= 369) Then
Return RTENAME
ElseIf (resType >= 370) AndAlso (resType <= 379) Then
Return RTSHORT
ElseIf (resType >= 380) AndAlso (resType <= 389) Then
Return RTSHORT
ElseIf (resType >= 390) AndAlso (resType <= 399) Then
Return RTENAME
ElseIf (resType >= 400) AndAlso (resType <= 409) Then
Return RTSHORT
ElseIf (resType >= 410) AndAlso (resType <= 419) Then
Return RTSTR
ElseIf resType = 1004 Then
Return resType ' binary chunk
ElseIf (resType >= 999) AndAlso (resType <= 1009) Then
Return RTSTR
ElseIf (resType >= 1010) AndAlso (resType <= 1013) Then
Return RT3DPOINT
ElseIf (resType >= 1038) AndAlso (resType <= 1059) Then
Return RTREAL
ElseIf (resType >= 1060) AndAlso (resType <= 1070) Then
Return RTSHORT
ElseIf (resType = 1071) Then
Return RTLONG
ElseIf (resType < 0) OrElse (resType > 4999) Then
Return resType
Else
Return RTNONE
End If
End Function
Private Sub LoopRbChain(ByVal entData As resbuf*)
resbuf* tmp = entData
Dim valueStr As CString
'increase size of internal buffer from 128 to 512
valueStr.GetBuffer(512)
Dim count As Integer = 0 ' To monitor Matrix filling
Do While tmp
Dim dataType As Integer = dxfCodeToDataType(tmp-> restype)
Select Case dataType
Case RTSTR
If tmp-> restype = 1 Then 'For NWD Model file path
If tmp-> resval.rstring = NULL Then
valueStr = _T("(NULL)")
Else
valueStr.Format(_T("""%s"""), tmp-> resval.rstring)
nwdData.filePath = valueStr
End If
End If
Case RTREAL
If tmp-> restype = 40 Then
If nwdData.rreals.length() < 16 Then
nwdData.rreals.append(tmp-> resval.rreal)
End If
End If
Case RTENAME
If tmp-> restype = 340 Then
resbuf* args = acutNewRb(RTSTR)
acutNewString(_T("*"), args-> resval.rstring)
resbuf* entdata = acdbEntGetX(tmp-> resval.rlname, args)
LoopRbChain(entdata)
acutRelRb(args)
acutRelRb(entdata)
End If
End Select
tmp = tmp-> rbnext
Loop
Return
End Sub
Can you please make a small sample using P/Invoke to get the Navisworks filepath?