简述如下:
API帮助文档的例子ZHeightColors是用VBA写的,它首先通过GetExistingFacets获取当前实体的面片信息,基于此构造Client Graphics,然后沿着实体的包围盒Z方向,最小值位置设置为红色,最高值设置为蓝色,期间的颜色为渐变色。
VBA
Public Sub ZHeightColors() ' Get the surface body from the active document. Dim oPartDoc As PartDocument Set oPartDoc = ThisApplication.ActiveDocument Dim oSurfBody As SurfaceBody Set oSurfBody = oPartDoc.ComponentDefinition.SurfaceBodies.Item(1) Set oSurfBody = oPartDoc.ComponentDefinitions.Item(1).SurfaceBodies.Item(1) ' Delete the graphics data set and client graphics,if they exist. Dim oDataSets As GraphicsDataSets On Error Resume Next Set oDataSets = oPartDoc.GraphicsDataSetsCollection.Item("MyTest") If Err.Number = 0 Then oDataSets.Delete oPartDoc.ComponentDefinition.ClientGraphicsCollection.Item("MyTest").Delete oSurfBody.Visible = True ThisApplication.ActiveView.Update Exit Sub End If On Error GoTo 0 ' Determine the highest tolerance of the existing facet sets. Dim ToleranceCount As Long Dim ExistingTolerances() As Double Call oSurfBody.GetExistingFacetTolerances(ToleranceCount,ExistingTolerances) Dim i As Long Dim BestTolerance As Double For i = 0 To ToleranceCount - 1 If i = 0 Then BestTolerance = ExistingTolerances(i) ElseIf ExistingTolerances(i) < BestTolerance Then BestTolerance = ExistingTolerances(i) End If Next ' Get a set of existing facets. Dim iVertexCount As Long Dim iFacetCount As Long Dim adVertexCoords() As Double Dim adNormalVectors() As Double Dim aiVertexIndices() As Long Call oSurfBody.GetExistingFacets(BestTolerance,iVertexCount,iFacetCount,_ adVertexCoords,adNormalVectors,aiVertexIndices) ' Start a transaction. Dim oTrans As Transaction Set oTrans = ThisApplication.TransactionManager.StartTransaction(oPartDoc,"Z Height Colors") ' Create the graphics data sets collection. Set oDataSets = oPartDoc.GraphicsDataSetsCollection.Add("MyTest") ' Create the coordinate set and set it using the coordinates from the facets. Dim oGraphicsCoordSet As GraphicsCoordinateSet Set oGraphicsCoordSet = oDataSets.CreateCoordinateSet(1) Call oGraphicsCoordSet.PutCoordinates(adVertexCoords) ' Create the index set and set it using the indices from the facets. Dim oGraphicsIndexSet As GraphicsIndexSet Set oGraphicsIndexSet = oDataSets.CreateIndexSet(2) Call oGraphicsIndexSet.PutIndices(aiVertexIndices) ' Create the normal set and set it using the normals from the facets. Dim oGraphicsNormalSet As GraphicsNormalSet Set oGraphicsNormalSet = oDataSets.CreateNormalSet(3) Call oGraphicsNormalSet.PutNormals(adNormalVectors) ' Determine the min-max range of the body in Z. Dim dMinZ As Double dMinZ = oSurfBody.RangeBox.MinPoint.Z Dim dMaxZ As Double dMaxZ = oSurfBody.RangeBox.MaxPoint.Z Dim dHeightDifference As Double dHeightDifference = dMaxZ - dMinZ ' Allocate the array that will contain the color information. ' This array contains RGB values for each vertex. Dim abtColors() As Byte ReDim abtColors(0 To iVertexCount * 3 - 1) As Byte ' Load the array with color information for each vertex. For i = 0 To iVertexCount - 1 ' Get the Z height of the current vertex. Dim dZValue As Double dZValue = adVertexCoords(i * 3 + 2) ' Set the color information for the current vertex. It's computed by ' determining the percentage of the total Z range of the body this vertex ' is within. A color between red and blue is computed based on this percentage. ' Blue is at the minimum Z and Red is at the maximum Z with blending between. abtColors(i * 3) = ((dZValue - dMinZ) / dHeightDifference) * 255 abtColors(i * 3 + 1) = 0 abtColors(i * 3 + 2) = ((dMaxZ - dZValue) / dHeightDifference) * 255 Next ' Create the color set and set it using the array of rgb values just created. Dim oGraphicsColorSet As GraphicsColorSet Set oGraphicsColorSet = oDataSets.CreateColorSet(4) Call oGraphicsColorSet.PutColors(abtColors) ' Create the client graphics collection. Dim oClientGraphics As ClientGraphics Set oClientGraphics = oPartDoc.ComponentDefinition.ClientGraphicsCollection.Add("MyTest") ' Create a graphics node. Dim oGraphicNode As GraphicsNode Set oGraphicNode = oClientGraphics.AddNode(1) ' Create the triangle graphics. Dim oTriangles As TriangleGraphics Set oTriangles = oGraphicNode.AddTriangleGraphics ' Set varIoUs prroperties of the triangle graphics. oTriangles.CoordinateSet = oGraphicsCoordSet oTriangles.CoordinateIndexSet = oGraphicsIndexSet oTriangles.NormalSet = oGraphicsNormalSet oTriangles.NormalBinding = kPerVertexNormals oTriangles.NormalIndexSet = oGraphicsIndexSet oTriangles.ColorSet = oGraphicsColorSet oTriangles.ColorBinding = kPerVertexColors oTriangles.ColorIndexSet = oGraphicsIndexSet ' Turn off the display of the body. oSurfBody.Visible = False ' End the transaction. oTrans.End ' Update the view. ThisApplication.ActiveView.Update End Sub
将此段代码贴到VB.NET,调整一些语法错误,编译通过。运行会发现GetExistingFacets 失败。这是为什么呢?
1. 首先是在.NET 中定义COM的整型数组,需要用Integers. MSDN是这样说的
If you are interfacing with components not written for the .NET Framework,for example Automation or COM objects,keep in mind that Long has a different data width (32 bits) in other environments. If you are passing a 32-bit argument to such a component,declare it as Integer instead of Long in your new Visual Basic code.
2. 注意数组以0为起始序号,而很多VBA的数组定义为:
Dim stuff(1 to 10) As Double
3. VB.NET中需要对数组初始化,而不能只是定义。例如
Dim adVertexCoords() As Double
需要变成
Dim adVertexCoords() As Double = {}
基于这些注意事项,以上的VBA代码修改如下后,就能成功运行了。
VB.NET
Public Sub ZHeightColors() ' Get the surface body from the active document. Dim oPartDoc As PartDocument oPartDoc = m_invApp.ActiveDocument Dim oSurfBody As SurfaceBody oSurfBody = oPartDoc.ComponentDefinition.SurfaceBodies.Item(1) oSurfBody = oPartDoc.ComponentDefinitions.Item(1).SurfaceBodies.Item(1) ' Delete the graphics data set and client graphics,if they exist. Dim oDataSets As GraphicsDataSets On Error Resume Next oDataSets = oPartDoc.GraphicsDataSetsCollection.Item("MyTest") If Err.Number = 0 Then oDataSets.Delete() oPartDoc.ComponentDefinition.ClientGraphicsCollection.Item("MyTest").Delete() oSurfBody.Visible = True m_invApp.ActiveView.Update() Exit Sub End If On Error GoTo 0 ' Determine the highest tolerance of the existing facet sets. Dim ToleranceCount As Integer Dim ExistingTolerances() As Double = {} Call oSurfBody.GetExistingFacetTolerances(ToleranceCount,ExistingTolerances) Dim i As Integer Dim BestTolerance As Double For i = 0 To ToleranceCount - 1 If i = 0 Then BestTolerance = ExistingTolerances(i) ElseIf ExistingTolerances(i) < BestTolerance Then BestTolerance = ExistingTolerances(i) End If Next ' Get a set of existing facets. Dim iVertexCount As Integer Dim iFacetCount As Integer Dim adVertexCoords() As Double = {} Dim adNormalVectors() As Double = {} Dim aiVertexIndices() As Integer = {} Call oSurfBody.GetExistingFacets(BestTolerance,_ adVertexCoords,aiVertexIndices) ' Start a transaction. Dim oTrans As Transaction oTrans = m_invApp.TransactionManager.StartTransaction(oPartDoc,"Z Height Colors") ' Create the graphics data sets collection. oDataSets = oPartDoc.GraphicsDataSetsCollection.Add("MyTest") ' Create the coordinate set and set it using the coordinates from the facets. Dim oGraphicsCoordSet As GraphicsCoordinateSet oGraphicsCoordSet = oDataSets.CreateCoordinateSet(1) Call oGraphicsCoordSet.PutCoordinates(adVertexCoords) ' Create the index set and set it using the indices from the facets. Dim oGraphicsIndexSet As GraphicsIndexSet oGraphicsIndexSet = oDataSets.CreateIndexSet(2) Call oGraphicsIndexSet.PutIndices(aiVertexIndices) ' Create the normal set and set it using the normals from the facets. Dim oGraphicsNormalSet As GraphicsNormalSet oGraphicsNormalSet = oDataSets.CreateNormalSet(3) Call oGraphicsNormalSet.PutNormals(adNormalVectors) ' Determine the min-max range of the body in Z. Dim dMinZ As Double dMinZ = oSurfBody.RangeBox.MinPoint.Z Dim dMaxZ As Double dMaxZ = oSurfBody.RangeBox.MaxPoint.Z Dim dHeightDifference As Double dHeightDifference = dMaxZ - dMinZ ' Allocate the array that will contain the color information. ' This array contains RGB values for each vertex. Dim abtColors() As Byte ReDim abtColors(iVertexCount * 3 - 1) ' Load the array with color information for each vertex. For i = 0 To iVertexCount - 1 ' Get the Z height of the current vertex. Dim dZValue As Double dZValue = adVertexCoords(i * 3 + 2) ' Set the color information for the current vertex. It's computed by ' determining the percentage of the total Z range of the body this vertex ' is within. A color between red and blue is computed based on this percentage. ' Blue is at the minimum Z and Red is at the maximum Z with blending between. abtColors(i * 3) = ((dZValue - dMinZ) / dHeightDifference) * 255 abtColors(i * 3 + 1) = 0 abtColors(i * 3 + 2) = ((dMaxZ - dZValue) / dHeightDifference) * 255 Next ' Create the color set and set it using the array of rgb values just created. Dim oGraphicsColorSet As GraphicsColorSet oGraphicsColorSet = oDataSets.CreateColorSet(4) Call oGraphicsColorSet.PutColors(abtColors) ' Create the client graphics collection. Dim oClientGraphics As ClientGraphics oClientGraphics = oPartDoc.ComponentDefinition.ClientGraphicsCollection.Add("MyTest") ' Create a graphics node. Dim oGraphicNode As GraphicsNode oGraphicNode = oClientGraphics.AddNode(1) ' Create the triangle graphics. Dim oTriangles As TriangleGraphics oTriangles = oGraphicNode.AddTriangleGraphics ' Set varIoUs prroperties of the triangle graphics. oTriangles.CoordinateSet = oGraphicsCoordSet oTriangles.CoordinateIndexSet = oGraphicsIndexSet oTriangles.NormalSet = oGraphicsNormalSet oTriangles.NormalBinding = NormalBindingEnum.kPerVertexNormals oTriangles.NormalIndexSet = oGraphicsIndexSet oTriangles.ColorSet = oGraphicsColorSet oTriangles.ColorBinding = ColorBindingEnum.kPerVertexColors oTriangles.ColorIndexSet = oGraphicsIndexSet ' Turn off the display of the body. oSurfBody.Visible = False ' End the transaction. oTrans.End() ' Update the view. m_invApp.ActiveView.Update() End Sub