Correct object for Navisworks (ACAD_BIM_DEFINITIONS) ??

Correct object for Navisworks (ACAD_BIM_DEFINITIONS) ??

Bradleywalker12380
Advocate Advocate
1,898 Views
13 Replies
Message 1 of 14

Correct object for Navisworks (ACAD_BIM_DEFINITIONS) ??

Bradleywalker12380
Advocate
Advocate

I am trying to get the xrefs under the NOD ACAD_BIM_DEFINITIONS.

 

What I am unsure of it what to CTYPE the dictionary entry as.
Ex: PDFDef As PdfDefinition = CType(oTrans.GetObject(oDictEntry.Value, OpenMode.ForRead), PdfDefinition)

 

So instead of PdfDefinition what is the correct item for ACAD_BIM_DEFINITIONS?

 

In the debugger for the dictionary entry's object class I see:

 

AppName "AcBIMUnderlayDbx"

DxfName "AcDbNavisworksModelDef"


Thanks!

-B

0 Likes
Accepted solutions (4)
1,899 Views
13 Replies
Replies (13)
Message 2 of 14

_gile
Consultant
Consultant

Hi,

You should use some inspection tool such as MgdDbg.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 14

Bradleywalker12380
Advocate
Advocate

I just did, the Navisworks xref shows up as ImpEntity, and that is not available under .DatabseServices.

 

What other options are there?

0 Likes
Message 4 of 14

_gile
Consultant
Consultant

Did you search in the Navision specific libraries?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 14

_gile
Consultant
Consultant
Accepted solution

From my litlle knowledge ImpEntity is quite similar to ProxyEntity.

Tony Tanzillo siad in this topic:

"ImpEntity is one of the managed wrapper types that
get created, if there is no application-specific managed
wrapper implemented for a given custom object type,
or the managed wrappers for the custom object are not
being loaded."



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 14

Bradleywalker12380
Advocate
Advocate

I googled and searched the forums but there is no documentation on that.

That is a shame if ImpEntity similar to a Proxy Object, because ImpEntity is not even possible to use.

 

I wonder if @moogalm could possibly verify this, please.

 

Madhukar, if you read this: Is there an actual object that can be used in DotNet to get Navisworks NWD/NWC files from the NamedObjectsDictionary ACAD_POINTCLOUD_EX_DICT?

 

(Similar when using PdfDefinition for getting PDF Underlay xrefs from DBDictionaryEntry)

 

Thank you!

-B

 

0 Likes
Message 7 of 14

Alexander.Rivilis
Mentor
Mentor

Read this topic: https://adndevblog.typepad.com/autocad/2016/11/how-to-retrieve-naviswork-model-nwd-or-bim-underlay-i...

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 8 of 14

Bradleywalker12380
Advocate
Advocate

thank you, i had read that but it is in C++ and I dont know that language. I use VB, if it was C# I could convert it at least. Will try to find a c++ converter.

0 Likes
Message 9 of 14

Alexander.Rivilis
Mentor
Mentor
Accepted solution

I don't think you can find a translator from C++ to VB.NET. The problem is that the code in the article is using ObjectARX and you are using the AutoCAD .NET API. These are different things. And besides, in the AutoCAD .NET API there are no direct methods for working with dxf-codes of entities, like acedEntGet in ObjectARX. So you have to use P/Invoke.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 10 of 14

Bradleywalker12380
Advocate
Advocate

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?

0 Likes
Message 11 of 14

Alexander.Rivilis
Mentor
Mentor
Accepted solution

Small sample of P/Invoke: https://stackoverflow.com/questions/30163338/c-sharp-wrapper-for-acdbentget-and-acdbentgetx

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 12 of 14

moogalm
Autodesk Support
Autodesk Support
Accepted solution

All Imp* classes like ImpEntity, ImpDBObject, ImpObject, ImpCurve.. etc are internal classes to AcDbMgd assembly can only be accessed from within the assembly it is defined (or friend assemblies), users of this assembly are prevented from using them.

 

What role does this Imp* plays, why are they are here in first place.

  1. In absence of respective Object Enabler, the object or entity is identified with ImpDbObject or ImpEntity respectively.

Unfortunately there is no .NET API to handle the information,  in this blog we decided to read information of Dxf data.

https://adndevblog.typepad.com/autocad/2016/11/how-to-retrieve-naviswork-model-nwd-or-bim-underlay-i...

0 Likes
Message 13 of 14

moogalm
Autodesk Support
Autodesk Support
0 Likes
Message 14 of 14

Bradleywalker12380
Advocate
Advocate

Thank you for the explanations @moogalm, @Alexander.Rivilis and @_gile .

I am not an (expert) programmer like you guys by any means, I strictly use .Net only (and convert c# to vb with a tool, so if its not one of those two languages its a roadblock for me).

Also since the BIM is not accessible in mgdbd (for strict ObjectARX) and only in accore I will need to give up on the BIM xref.

 

At least now I know why things were not behaving as I suspected.

 

Much appreciated anyways!!!!

-B

0 Likes