[Microstation V8i] MDL Mesh Functions in VBA

Hi All,

Can anyone give me an example of how to use the MDL mesh function mdlMesh_getPolyfaceArraysDirect.

I'm struggling to understand how to pass the int and point3d arrays into the VBA decleration as Longs.

Declare Function mdlMesh_getPolyfaceArraysDirect Lib "stdbspline.dll" ( ByVal pMeshHeaderED As Long , ByVal pIndices As Long , ByVal pXYZ As Long , ByRef pNumIndexPerFace As Long , ByRef pNumFace As Long ) As Long

Return Value

Type Description
StatusInt SUCCESS if the desired output is successfully returned

Parameters

Type Name Mode Description
MSElementDescr const* pMeshHeaderED IN top of descriptor tree containing the mesh.
EmbeddedIntArray* pIndices OUT polyface index array.
EmbeddedDPoint3dArray* pXYZ OUT vertex coordinate array (3D points).
int* pNumIndexPerFace OUT max number of indices/vertices per face (= 1 if variable-size face loops)
int* pNumFace OUT number of faces (#entries in index array if variable-size face loops).

    Dim success As Long
    Dim element As element
    Dim indicies() As Long
    Dim verticies() As Point3d
    Dim numOfIndicies As Long
    Dim numOfFaces As Long
    
    success = mdlMesh_getPolyfaceArraysDirect(element.MdlElementDescrP(False), indicies, verticies, numOfIndicies, numOfFaces)

Kind Regards,

Mike

Parents
  • I'm struggling to understand how to pass the int and point3d arrays into the VBA decleration as Longs

    First, add the VBA function declaration to your VBA module.  This is copied from the MDL function reference manual...

    VBA Wrapper Declaration

    Declare Function mdlMesh_getPolyfaceArraysDirect Lib "stdbspline.dll" ( _
            ByVal pMeshHeaderED As Long , _
            ByVal pIndices As Long , _
            ByVal pXYZ As Long , _
            ByRef pNumIndexPerFace As Long , _
            ByRef pNumFace As Long ) As Long
    

    Undocumented Helpers for Pointers in VBA

    Because VBA doesn't do pointers, the VBA declaration writes MDL pointers as VBA Long.

    VBA arrays are SafeArrays.  Their structure is quite unlike the C-style arrays used in MDL.  The first three parameters in that function declaration, passed ByVal, are pointers to arrays.

    Microsoft provide some undocumented helpers for exactly your sort of task: look them up here.

     
    Regards, Jon Summers
    LA Solutions

    Answer Verified By: Michael Laws 

  • Thanks Jon, this is exactly what I'm looking for. As always, very helpfull! 

  • Hi Micheal,

    I have the same problem, but unfortunately I'm not getting anywhere with the tip from Jon.

    Could you please show me how you got the content of the array's pIndices and pXYZ?

    with best greetings

    Tobias

  • Hi Tobias,

    Could you please show me how you got the content of the array's pIndices and pXYZ?

    there can be a problem that this (2 years old) discussion is about MicroStation V8i (SELECTseries 4), whereas your question (not bad idea to provide proper link) is about MicroStation CONNECT Edition.

    How native functions are called changed a bit, both because of migration from 32bit to 64bit, and also from VBA 6 to VBA 7. As described in "Changes for VBA 7.1" chapter (did you check this text in MicroStation VBA help?), different data types have to be used (e.g. where pointer was passed as long, now it has to be PtrSafe).

    With regards,

      Jan

  • Hi Jan,

    yes, I have read the chapter.
    I have about 10 mdl functions that I migrated from v8i to connect (insert ptrsave and change type fom long to longptr).

    But I have never had a mdl function with an array as output. 

    So I wanted to ask Micheal for his (v8i) solution and migrate it (hopefully) to connect.

    here I'm stuck:

    Declare PtrSafe Function mdlMesh_getPolyfaceArraysDirect Lib "stdbspline.dll" ( _
            ByVal pMeshHeaderED As LongPtr, _
            ByVal pIndices As LongPtr, _
            ByVal pXYZ As LongPtr, _
            ByRef pNumIndexPerFace As Long, _
            ByRef pNumFace As Long) As Long

    Function Mesh_auslesen(o_Mesh As Element) As Point3d()
    Dim o_pIndices As LongPtr
    Dim o_pXYZ As LongPtr
    Dim o_pNumIndexPerFace As Long
    Dim o_pNumFace As Long
    
    
    If 0 = mdlMesh_getPolyfaceArraysDirect (o_Mesh.MdlElementDescrP(False), o_pIndices, o_pXYZ, o_pNumIndexPerFace, o_pNumFace) Then
    
    ...
    
    End If
    
    
    End Function

    For o_pNumIndexPerFace and o_pNumFace I get matching values. But no matter how I use varptr, strptr. (e.g:

    Function Mesh_auslesen(o_Mesh As Element) As Point3d()
    Dim o_pIndices As LongPtr
    Dim o_pXYZ As Point3d 'no array possible
    Dim o_pNumIndexPerFace As Long
    Dim o_pNumFace As Long
    
    
    If 0 = mdlMesh_getPolyfaceArraysDirect(o_Mesh.MdlElementDescrP(False), o_pIndices, VarPtr(o_pXYZ), o_pNumIndexPerFace, o_pNumFace) Then
    
    End If
    
    
    End Function
    )

    I get only nonsense for  o_pXYZ (and o_pIndices).

    Can you help me to use the functions here correctly?

Reply
  • Hi Jan,

    yes, I have read the chapter.
    I have about 10 mdl functions that I migrated from v8i to connect (insert ptrsave and change type fom long to longptr).

    But I have never had a mdl function with an array as output. 

    So I wanted to ask Micheal for his (v8i) solution and migrate it (hopefully) to connect.

    here I'm stuck:

    Declare PtrSafe Function mdlMesh_getPolyfaceArraysDirect Lib "stdbspline.dll" ( _
            ByVal pMeshHeaderED As LongPtr, _
            ByVal pIndices As LongPtr, _
            ByVal pXYZ As LongPtr, _
            ByRef pNumIndexPerFace As Long, _
            ByRef pNumFace As Long) As Long

    Function Mesh_auslesen(o_Mesh As Element) As Point3d()
    Dim o_pIndices As LongPtr
    Dim o_pXYZ As LongPtr
    Dim o_pNumIndexPerFace As Long
    Dim o_pNumFace As Long
    
    
    If 0 = mdlMesh_getPolyfaceArraysDirect (o_Mesh.MdlElementDescrP(False), o_pIndices, o_pXYZ, o_pNumIndexPerFace, o_pNumFace) Then
    
    ...
    
    End If
    
    
    End Function

    For o_pNumIndexPerFace and o_pNumFace I get matching values. But no matter how I use varptr, strptr. (e.g:

    Function Mesh_auslesen(o_Mesh As Element) As Point3d()
    Dim o_pIndices As LongPtr
    Dim o_pXYZ As Point3d 'no array possible
    Dim o_pNumIndexPerFace As Long
    Dim o_pNumFace As Long
    
    
    If 0 = mdlMesh_getPolyfaceArraysDirect(o_Mesh.MdlElementDescrP(False), o_pIndices, VarPtr(o_pXYZ), o_pNumIndexPerFace, o_pNumFace) Then
    
    End If
    
    
    End Function
    )

    I get only nonsense for  o_pXYZ (and o_pIndices).

    Can you help me to use the functions here correctly?

Children