不知您是否在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();
}