不知您是否在MicroStation中看到过如下的彩色Mesh元素?它每个顶点可以被赋以不同的颜色,这种应用可扩展到专题显示样式(Thematic Display Style)中。
下面这段代码就是用来创建图一所示的彩色Mesh元素的。
void createVertexColoredMesh() { // index= 1, 2, 3, 4, DPoint3d xyzPts[] = { { -577350, 0, -816497 }, { -577350, 0, 816497 }, { 577350, -816497, 0 }, { 577350, 816497, 0 } }; //Face= 1, 2, 3, 4 int indices[] = { 1, 2, 4, 2, 3, 4, 3, 2, 1, 1, 4, 3 }; int vertexClrs[] = { RGB(255, 0, 0), RGB(0, 255, 0), RGB(0, 0, 255), RGB(255, 255, 0) }; EmbeddedIntArray *pIndices = jmdlEmbeddedIntArray_grab(); jmdlEmbeddedIntArray_addIntArray(pIndices, indices, sizeof(indices) / sizeof(int)); EmbeddedDPoint3dArray *pXYZArray = jmdlEmbeddedDPoint3dArray_grab(); jmdlEmbeddedDPoint3dArray_addDPoint3dArray(pXYZArray, xyzPts, sizeof(xyzPts) / sizeof(DPoint3d)); EmbeddedIntArray *pClrArray = jmdlEmbeddedIntArray_grab(); jmdlEmbeddedIntArray_addIntArray(pClrArray, vertexClrs, sizeof(vertexClrs) / sizeof(int)); MSElementDescrP meshP = NULL; mdlMesh_newPolyfaceFromEmbeddedArraysExt(&meshP, NULL, pIndices, 3, pXYZArray, NULL, NULL, NULL, NULL, pIndices, pClrArray, NULL, NULL, FALSE, TRUE); if (NULL != meshP) { mdlElmdscr_add(meshP); mdlElmdscr_freeAll(&meshP); } jmdlEmbeddedIntArray_drop(pIndices); jmdlEmbeddedDPoint3dArray_drop(pXYZArray); jmdlEmbeddedIntArray_drop(pClrArray); }
下面对以上代码做简单的介绍:
1、首先做数据准备,在xyzPts数组中指定四面体的四个坐标点,然后在vertexClrs数组中指定每个顶点的颜色。
2、关键在于定义indices。Mesh元素的每个面可以说固定顶点个数的也可以是不定个数的,我们这里采用了固定个数(每个面由三个点组成)。所以,在indices中定义了12个数,每三个数定义了四面体的一个面的索引。如Face1的索引为1,2,4,那它的三个坐标点就是xyzPts[0]、xyzPts[1]和xyzPts[3],对应的颜色就是vertexClrs[0]、vertexClrs[1]和vertexClrs[3]。这是因为Mesh的索引要从1开始计数,0作为特殊含义(每个面不固定个数顶点时要以0作为索引的分隔)的索引。
3、由于mdlMesh_newPolyfaceFromEmbeddedArraysExt函数需要传入动态数组,所以,接下来调用了jmdlEmbedded类函数将xyzPts、vertexClrs和indices分别转换为了pXYZArray、pClrArray和pIndices。
4、调用函数mdlMesh_newPolyfaceFromEmbeddedArraysExt创建彩色Mesh,并将其添加到模型中。
5、调用jmdlEmbeddedXXXArray_drop函数释放pXYZArray、pClrArray和pIndices占用的内存。
————————————————————————————————————————————————————
以上代码是在MicroStation V8i下用C++编写而成的。随着MicroStation CE版的流行,下面是用C++最新的面向对象方法重写的代码:
#define RGB(r,g,b) ((r)|((g)<<8)|((b)<<16)) void meshCreateFixedIndex(WCharCP unparsed) { // index= 1, 2, 3, 4, DPoint3d xyzPts[] = { { -57735, 0, -81649 }, { -57735, 0, 81649 }, { 57735, -81649, 0 }, { 57735, 81649, 0 } }; //Face= 1, 2, 3, 4 int indices[] = { 1, 2, 4, 2, 3, 4, 3, 2, 1, 1, 4, 3 }; int vertexClrs[] = { RGB(255, 0, 0), RGB(0, 255, 0), RGB(0, 0, 255), RGB(255, 255, 0) }; PolyfaceHeaderPtr pMesh = PolyfaceHeader::CreateFixedBlockIndexed(3); pMesh->Point().insert(pMesh->Point().begin(), xyzPts, xyzPts + sizeof(xyzPts) / sizeof(DPoint3d)); pMesh->Point().SetActive(true); pMesh->PointIndex().insert(pMesh->PointIndex().begin(), indices, indices + sizeof(indices) / sizeof(int)); pMesh->PointIndex().SetActive(true); pMesh->IntColor().insert(pMesh->IntColor().begin(), vertexClrs, vertexClrs + sizeof(vertexClrs) / sizeof(int)); pMesh->IntColor().SetActive(true); pMesh->ColorIndex().insert(pMesh->ColorIndex().begin(), indices, indices + sizeof(indices) / sizeof(int)); pMesh->ColorIndex().SetActive(true); EditElementHandle eeh; DgnModelP pActiveModel = ISessionMgr::GetActiveDgnModelP(); if (SUCCESS == MeshHeaderHandler::CreateMeshElement(eeh, NULL, *pMesh, true, *pActiveModel)) { eeh.AddToModel(); } }
下面是用CE下的C#重写的代码:
public static void CreateMesh2() { PolyfaceHeader polyHeader = new PolyfaceHeader(); polyHeader.NumberPerFace = 0; var pts = new List<DPoint3d>(); pts.Add(new DPoint3d(-57735, 0, -81649)); pts.Add(new DPoint3d(-57735, 0, 81649)); pts.Add(new DPoint3d(57735, -81649, 0)); pts.Add(new DPoint3d(57735, 81649, 0)); polyHeader.Point = pts; var clrs = new List<uint>(); clrs.Add(0x000000ff); // RED clrs.Add(0x0000ff00); // GREEN clrs.Add(0x00ff0000); // BLUE clrs.Add(0x0000ffff); polyHeader.IntColor = clrs; polyHeader.ActivateVectorsForIndexing(polyHeader); var indices = new List<int>(); indices.Add(1); indices.Add(2); indices.Add(4); //one-based polyHeader.AddIndexedFacet(indices, null, null, indices); indices.Clear(); indices.Add(2); indices.Add(3); indices.Add(4); polyHeader.AddIndexedFacet(indices, null, null, indices); indices.Clear(); indices.Add(3); indices.Add(2); indices.Add(1); polyHeader.AddIndexedFacet(indices, null, null, indices); indices.Clear(); indices.Add(1); indices.Add(4); indices.Add(3); polyHeader.AddIndexedFacet(indices, null, null, indices); DgnModel dgnModel = Session.Instance.GetActiveDgnModel(); MeshHeaderElement meshElem = new MeshHeaderElement(dgnModel, null, polyHeader); meshElem.AddToModel(); }