Dynamic Block Point Parameter Visibility

Dynamic Block Point Parameter Visibility

GeeHaa
Collaborator Collaborator
1,377 Views
9 Replies
Message 1 of 10

Dynamic Block Point Parameter Visibility

GeeHaa
Collaborator
Collaborator

Hi

 

I Posted this at the end of a post that had a solution so I don't think anyone looked at. Sorry for posting it again.

 

http://adndevblog.typepad.com/autocad/2012/05/accessing-visible-entities-in-a-dynamic-block.html

 

Hi I'm having trouble with the code in the suggested solution above. I translated it to VB.net and I am getting an error EntryPoint "?" not found in acdb19.dll. I'm using acdb19.dll because it couldn't find acdb18.dll any suggestions would be much appreciated.

 

Thanks

 

Public Sub DynablockVisibilityStates()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
                        Dim per As PromptEntityResult = ed.GetEntity(vbLf + "Select Dynamic Block ")


            If per.Status <> PromptStatus.OK Then
                Return
            End If

            Using myTrans As Transaction = db.TransactionManager.StartTransaction()

                Dim ent As Entity = myTrans.GetObject(per.ObjectId, OpenMode.ForRead)
                Dim bref As BlockReference = Nothing
                If TypeOf ent Is BlockReference Then
                    bref = ent
                End If

                Dim bt As BlockTable = TryCast(myTrans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                               Dim btr As BlockTableRecord = myTrans.GetObject(bref.DynamicBlockTableRecord, OpenMode.ForRead)


                               If Not btr.IsDynamicBlock Then
                    ed.WriteMessage(vbLf & "Not a dynamic block :(")
                    Return
                End If
                If btr.ExtensionDictionary = Nothing Then
                    ed.WriteMessage(vbLf & "No ExtensionDictionary :(")
                    Return
                End If

                Dim dict As DBDictionary = TryCast(myTrans.GetObject(btr.ExtensionDictionary, OpenMode.ForRead), DBDictionary)
                If Not dict.Contains("ACAD_ENHANCEDBLOCK") Then
                    ed.WriteMessage(vbLf & "ACAD_ENHANCEDBLOCK Entry not found :(")
                    Return
                End If
                Dim graphId As ObjectId = dict.GetAt("ACAD_ENHANCEDBLOCK")
                Dim parameterIds As System.Collections.Generic.List(Of Object) = acdbEntGetObjects(graphId, 360)

                For Each parameterId As Object In parameterIds
                    Dim id As ObjectId = DirectCast(parameterId, ObjectId)

                    If id.ObjectClass.Name = "AcDbBlockVisibilityParameter" Then
                        Dim visibilityParam As System.Collections.Generic.List(Of TypedValue) = acdbEntGetTypedVals(id)
                        Dim enumerator As System.Collections.Generic.List(Of TypedValue).Enumerator = visibilityParam.GetEnumerator()

                        While enumerator.MoveNext()
                            If enumerator.Current.TypeCode = 303 Then
                                Dim group As String = DirectCast(enumerator.Current.Value, String)
                                enumerator.MoveNext()
                                Dim nbEntitiesInGroup As Integer = CInt(enumerator.Current.Value)
                                ed.WriteMessage((Convert.ToString(vbLf & " . Visibility Group: ") & group) + " Nb Entities in group: " + nbEntitiesInGroup)
                                For i As Integer = 0 To nbEntitiesInGroup - 1
                                    enumerator.MoveNext()
                                    Dim entityId As ObjectId = DirectCast(enumerator.Current.Value, ObjectId)
                                    Dim entity As Entity = TryCast(myTrans.GetObject(entityId, OpenMode.ForRead), Entity)
                                    ed.WriteMessage(vbLf & "    - " + entity.ToString() + " " + entityId.ToString())
                                Next

                            End If
                        End While


                        Exit For

                    End If
                Next
                myTrans.Commit()
            End Using

        End Sub



        Public Structure ads_name
            Private a As IntPtr
            Private b As IntPtr
        End Structure

        <Runtime.InteropServices.DllImport("acdb19.dll", CallingConvention:=System.Runtime.InteropServices.​CallingConvention.Cdecl, EntryPoint:="?acdbGetAdsName@@YA?AW4ErrorStatus@Ac​ad@@AAY01JVAcDbObjectId@@@Z")> _
        Public Shared Function acdbGetAdsName(ByRef name As ads_name, objId As ObjectId) As Integer
        End Function


        <Runtime.InteropServices.DllImport("acad.exe", CharSet:=System.Runtime.InteropServices.CharSet.An​si, CallingConvention:=System.Runtime.InteropServices.​CallingConvention.Cdecl, EntryPoint:="acdbEntGet")> _
        Public Shared Function acdbEntGet(ByRef ename As ads_name) As System.IntPtr
        End Function

        Private Function acdbEntGetObjects(id As ObjectId, dxfcode As Short) As System.Collections.Generic.List(Of Object)
            Dim result As New System.Collections.Generic.List(Of Object)()
            Dim name As New ads_name()
            Dim res As Integer = acdbGetAdsName(name, id)
            Dim rb As New ResultBuffer()
            Autodesk.AutoCAD.Runtime.Interop.AttachUnmanagedOb​ject(rb, acdbEntGet(name), True)
            Dim iter As ResultBufferEnumerator = rb.GetEnumerator()

            While iter.MoveNext()
                Dim typedValue As TypedValue = CType(iter.Current, TypedValue)
                If typedValue.TypeCode = dxfcode Then
                    result.Add(typedValue.Value)
                End If
            End While

            Return result
        End Function

        Private Function acdbEntGetTypedVals(id As ObjectId) As System.Collections.Generic.List(Of TypedValue)
            Dim result As New System.Collections.Generic.List(Of TypedValue)()
            Dim name As New ads_name()
            Dim res As Integer = acdbGetAdsName(name, id)
            Dim rb As New ResultBuffer()
            Autodesk.AutoCAD.Runtime.Interop.AttachUnmanagedOb​ject(rb, acdbEntGet(name), True)
            Dim iter As ResultBufferEnumerator = rb.GetEnumerator()

            While iter.MoveNext()
                result.Add(CType(iter.Current, TypedValue))
            End While

            Return result

        End Function



    End Class

 

0 Likes
1,378 Views
9 Replies
Replies (9)
Message 2 of 10

_gile
Consultant
Consultant

Hi,

 

Try with this EntryPoint:

"?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z"

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 10

GeeHaa
Collaborator
Collaborator

Hi,

Thanks for the reply. Unfortunately I get the same error.

 

An exception of type 'System.EntryPointNotFoundException' occurred in CheckVisibilityofPoints.dll but was not handled in user code
 
Additional information: Unable to find an entry point named '?' in DLL 'acdb19.dll'.
 
If there is a handler for this exception, the program may be safely continued.
 
Here is the modified Statement.
 
       <Runtime.InteropServices.DllImport("acdb19.dll", CallingConvention:=System.Runtime.InteropServices.CallingConvention.Cdecl, CharSet:=System.Runtime.InteropServices.CharSet.Ansi, EntryPoint:="?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_J​VAcDbObjectId@@@Z")> _
        Public Shared Function acdbGetAdsName(ByRef name As ads_name, objId As ObjectId) As Integer
        End Function
 
It actually crashes whet it hits this statement.       Dim res As Integer = acdbGetAdsName(name, id)
 
The variable "name" has the values A=0 and B=0
 
Sorry I didn't see your reply right away.
Thanks again I appreciate the help.
0 Likes
Message 4 of 10

Anonymous
Not applicable

Hi,

 

I need to have this answered as well or point me in another direction.

 

Thanks

0 Likes
Message 5 of 10

_gile
Consultant
Consultant

Hi,

 

The EntryPoint isn't the same for 32 bits or 64 bits platform:

  • 32 bits: ?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z
  • 64 bits: ?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z

You can see this topic.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 10

_gile
Consultant
Consultant

For R19 and later, you also have to replace "acad.exe" with "accore.dll" to P/Invoke acdbEntGet() method.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 10

GeeHaa
Collaborator
Collaborator

Thanks for the Responses

 

Thanks to you both. It works now. Unfortunately it doesn't retrieve the Point Parameters in any of the Visibility groups. Its only showing entities. Is there a way to see the point parameters as well?

 

Thanks

0 Likes
Message 8 of 10

_gile
Consultant
Consultant

What are you trying to achieve?

You can easily access to the dynamic properties and their values and you probably know which entities are visible according to the visibility state.

 

        [CommandMethod("dynprops")]
        public void GetDynamicProperties()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var opts = new PromptEntityOptions("\nSelect a block: ");
            opts.SetRejectMessage("Must be a block.");
            opts.AddAllowedClass(typeof(BlockReference), true);
            var res = ed.GetEntity(opts);
            if (res.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var br = (BlockReference)tr.GetObject(res.ObjectId, OpenMode.ForRead);
                if (br.IsDynamicBlock)
                {
                    foreach (DynamicBlockReferenceProperty prop in br.DynamicBlockReferencePropertyCollection)
                    {
                        ed.WriteMessage("\n{0} ({1}) = {2}", prop.PropertyName, prop.PropertyTypeCode, prop.Value);
                    }
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 10

GeeHaa
Collaborator
Collaborator

I have a program that attaches polylines to point parameters on Dynamic blocks right now it connects to all the points on the block whether they are visible or not. I just want to connect to the visible ones.

 

Thanks

0 Likes
Message 10 of 10

GeeHaa
Collaborator
Collaborator

These are the typecodes and values for the two PointParameters in a particular Dynamic Block  I'm probably thinking about this all wrong (I don't have much experience with dictionaries) but I have the objectIDs of the Point parameters. Is there a class I could cast them  into that would give me a visibility state? Internal.databaseServices.Block1PointParameter has everything else but a Visibility State. I even checked the XData..There must be a way to do this. When I select this block in different visibility states only the point parameters of that state show(as grips). Otherwise you cant see them.

 

All the blocks (there are a few hundred of them) have different names for visibility states so I can't tell which parameters go with what states. Since programmatically I can only get entities from the Visibility states.

 

Thanks Again for all your help

 

- -1 (140699525757456)
    - 0 BLOCKPOINTPARAMETER
    - 330 (140699525757376)
    - 5 459
    - 100 AcDbEvalExpr
    - 90 5
    - 98 31
    - 99 106
    - 100 AcDbBlockElement
    - 300 Point
    - 98 31
    - 99 106
    - 1071 0
    - 100 AcDbBlockParameter
    - 280 1
    - 281 0
    - 100 AcDbBlock1PtParameter
    - 1010 (1.5,-0.125,0)
    - 93 6
    - 170 1
    - 91 6
    - 301 DisplacementX
    - 171 1
    - 92 6
    - 302 DisplacementY
    - 100 AcDbBlockPointParameter
    - 303 ConnPt01
    - 304 Connection Point 01
    - 1011 (1.6875,-0.125,0)
 
    - -1 (140699525757552)
    - 0 BLOCKPOINTPARAMETER
    - 330 (140699525757376)
    - 5 45F
    - 100 AcDbEvalExpr
    - 90 16
    - 98 31
    - 99 106
    - 100 AcDbBlockElement
    - 300 Point1
    - 98 31
    - 99 106
    - 1071 0
    - 100 AcDbBlockParameter
    - 280 1
    - 281 0
    - 100 AcDbBlock1PtParameter
    - 1010 (1.5,-0.875,0)
    - 93 17
    - 170 1
    - 91 17
    - 301 DisplacementX
    - 171 1
    - 92 17
    - 302 DisplacementY
    - 100 AcDbBlockPointParameter
    - 303 ConnPt02
    - 304 Connection Point 02
    - 1011 (1.6875,-0.875,0)
0 Likes