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
Parameters
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
Michael Laws said: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...
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
Because VBA doesn't do pointers, the VBA declaration writes MDL pointers as VBA Long.
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.
ByVal
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,
Tobias Koeppen said: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
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
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?
Tobias Koeppen said:So I wanted to ask Micheal for his (v8i) solution and migrate it (hopefully) to connect.
I do not want to be too pessimistic, but I think it's not straightforward, because V8i function returns EmbeddedIntArray and EmbeddedDPoint3dArray (which are originally JMDL structures), whereas CE function returns bvector (which is Bentley implementation of std:vector).
So I think it makes sense to continue in this discussion in your original thread (because it's about CE).
Tobias Koeppen said:But I have never had a mdl function with an array as output.
It's not array, the function returns vector. I do not know whether C++ vector class can be accessed as array or not.
Jan Šlegr said:I do not know whether C++ vector class can be accessed as array
The C++ standard requires std::vector to organise its contents as a contiguous chunk of memory, just like an array. In C++ we can get at the data of a std::vector as if it were an array...
std::vector
std::vector<something> vSomething; something pointerToArray* = &vSomething[0];
However, I can't see a way to translate that to VBA.
Tobias Koeppen said:Can you help me to use the functions here correctly [with MicroStation CONNECT]?
I don't think it's possible. In general, VBA and C++ don't mix. It's possibly only when C++ defines a function using a C-style syntax and when its parameters are C-style primitive variables or data-only structures.
For example, MDL is an implementation of C and VBA can call its functions. Likewise with the Microsoft Win32 API. But technology has moved on! VBA is a 20th century technology and we're now about to enter the third decade of the 21st century.
st
Jan Šlegr said:Probably a right time to start to think about a migration
I agree!
Jon Summers said:The C++ standard requires std::vector to organise its contents as a contiguous chunk of memory, just like an array. In C++ we can get at the data of a std::vector as if it were an array...
Well, I think I really do not need to explain what std::vector is and how it works ;-)
But it's true my notice was not precise enough as I at that moment thought it's clear from its content: How std::vector (as memory structure identified by its pointer) can be accessed from VBA.
Regards,