From 545aa92d14cdc26b6f33bfcf9218cd864dfe6e45 Mon Sep 17 00:00:00 2001 From: David Williams Date: Mon, 21 Apr 2008 18:53:56 +0000 Subject: [PATCH] Switched to floats for vetex positions ready for mesh smoothing. Added new way to detect duplicate vertices but it's not enabled as it doesn't work yet... --- include/GradientEstimators.inl | 9 +- include/IndexedSurfacePatch.h | 6 ++ source/IndexedSurfacePatch.cpp | 63 +++++++++++++- source/PolyVoxSceneManager.cpp | 148 ++++++++++++++++----------------- 4 files changed, 148 insertions(+), 78 deletions(-) diff --git a/include/GradientEstimators.inl b/include/GradientEstimators.inl index 924eda4d..c7d4421f 100644 --- a/include/GradientEstimators.inl +++ b/include/GradientEstimators.inl @@ -22,7 +22,12 @@ namespace PolyVox VoxelType voxel1nz = volIter.peekVoxel0px0py1nz() > 0 ? 1: 0; VoxelType voxel1pz = volIter.peekVoxel0px0py1pz() > 0 ? 1: 0; - return Vector3DFloat(int(voxel1px) - int(voxel1nx),int(voxel1py) - int(voxel1ny),int(voxel1pz) - int(voxel1nz)); + return Vector3DFloat + ( + static_cast(voxel1px) - static_cast(voxel1nx), + static_cast(voxel1py) - static_cast(voxel1ny), + static_cast(voxel1pz) - static_cast(voxel1nz) + ); } template @@ -114,6 +119,6 @@ namespace PolyVox weights[0][2][2] * ( pVoxel1px1py1nz) + weights[2][2][2] * ( pVoxel1px1py1pz)); - return Vector3DFloat(xGrad,yGrad,zGrad); + return Vector3DFloat(static_cast(xGrad),static_cast(yGrad),static_cast(zGrad)); } } \ No newline at end of file diff --git a/include/IndexedSurfacePatch.h b/include/IndexedSurfacePatch.h index 88a670b0..3bc147ff 100644 --- a/include/IndexedSurfacePatch.h +++ b/include/IndexedSurfacePatch.h @@ -26,6 +26,9 @@ namespace PolyVox std::vector m_vecVertices; static long int vertexIndices[POLYVOX_REGION_SIDE_LENGTH*2+1][POLYVOX_REGION_SIDE_LENGTH*2+1][POLYVOX_REGION_SIDE_LENGTH*2+1]; + static boost::int32_t vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH]; + static boost::int32_t vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH]; + static boost::int32_t vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH]; static long int noOfVerticesSubmitted; static long int noOfVerticesAccepted; @@ -33,6 +36,9 @@ namespace PolyVox long int getSizeInBytes(void); + boost::int32_t getIndexFor(const Vector3DFloat& pos); + void setIndexFor(const Vector3DFloat& pos, boost::int32_t newIndex); + private: bool m_AllowDuplicateVertices; }; diff --git a/source/IndexedSurfacePatch.cpp b/source/IndexedSurfacePatch.cpp index 58b22932..534595ee 100644 --- a/source/IndexedSurfacePatch.cpp +++ b/source/IndexedSurfacePatch.cpp @@ -8,11 +8,17 @@ namespace PolyVox long int IndexedSurfacePatch::noOfVerticesAccepted = 0; long int IndexedSurfacePatch::noOfTrianglesSubmitted = 0; long int IndexedSurfacePatch::vertexIndices[POLYVOX_REGION_SIDE_LENGTH*2+1][POLYVOX_REGION_SIDE_LENGTH*2+1][POLYVOX_REGION_SIDE_LENGTH*2+1]; + int32_t IndexedSurfacePatch::vertexIndicesX[POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH]; + int32_t IndexedSurfacePatch::vertexIndicesY[POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH]; + int32_t IndexedSurfacePatch::vertexIndicesZ[POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH][POLYVOX_REGION_SIDE_LENGTH]; IndexedSurfacePatch::IndexedSurfacePatch(bool allowDuplicateVertices) :m_AllowDuplicateVertices(allowDuplicateVertices) { - memset(vertexIndices,0xFF,sizeof(vertexIndices)); //0xFF is -1 as two's complement - this may not be portable... + memset(vertexIndices,0xFF,sizeof(vertexIndices)); + memset(vertexIndicesX,0xFF,sizeof(vertexIndicesX)); //0xFF is -1 as two's complement - this may not be portable... + memset(vertexIndicesY,0xFF,sizeof(vertexIndicesY)); + memset(vertexIndicesZ,0xFF,sizeof(vertexIndicesZ)); } IndexedSurfacePatch::~IndexedSurfacePatch() @@ -26,11 +32,13 @@ namespace PolyVox if(!m_AllowDuplicateVertices) { long int index = vertexIndices[long int(v0.getPosition().x() * 2.0 +0.5)][long int(v0.getPosition().y() * 2.0 +0.5)][long int(v0.getPosition().z() * 2.0 +0.5)]; + //int32_t index = getIndexFor(v0.getPosition()); if(index == -1) { m_vecVertices.push_back(v0); m_vecTriangleIndices.push_back(m_vecVertices.size()-1); vertexIndices[long int(v0.getPosition().x() * 2.0 +0.5)][long int(v0.getPosition().y() * 2.0 +0.5)][long int(v0.getPosition().z() * 2.0 +0.5)] = m_vecVertices.size()-1; + //setIndexFor(v0.getPosition(), m_vecVertices.size()-1); noOfVerticesAccepted++; } @@ -40,11 +48,13 @@ namespace PolyVox } index = vertexIndices[long int(v1.getPosition().x() * 2.0 +0.5)][long int(v1.getPosition().y() * 2.0 +0.5)][long int(v1.getPosition().z() * 2.0 +0.5)]; + //index = getIndexFor(v1.getPosition()); if(index == -1) { m_vecVertices.push_back(v1); m_vecTriangleIndices.push_back(m_vecVertices.size()-1); vertexIndices[long int(v1.getPosition().x() * 2.0 +0.5)][long int(v1.getPosition().y() * 2.0 +0.5)][long int(v1.getPosition().z() * 2.0 +0.5)] = m_vecVertices.size()-1; + //setIndexFor(v1.getPosition(), m_vecVertices.size()-1); noOfVerticesAccepted++; } @@ -54,11 +64,13 @@ namespace PolyVox } index = vertexIndices[long int(v2.getPosition().x() * 2.0 +0.5)][long int(v2.getPosition().y() * 2.0 +0.5)][long int(v2.getPosition().z() * 2.0 +0.5)]; + //index = getIndexFor(v2.getPosition()); if(index == -1) { m_vecVertices.push_back(v2); m_vecTriangleIndices.push_back(m_vecVertices.size()-1); vertexIndices[long int(v2.getPosition().x() * 2.0 +0.5)][long int(v2.getPosition().y() * 2.0 +0.5)][long int(v2.getPosition().z() * 2.0 +0.5)] = m_vecVertices.size()-1; + //setIndexFor(v2.getPosition(), m_vecVertices.size()-1); noOfVerticesAccepted++; } @@ -102,4 +114,53 @@ namespace PolyVox size += m_vecTriangleIndices.capacity() * sizeof(m_vecTriangleIndices[0]); return size; } + + boost::int32_t IndexedSurfacePatch::getIndexFor(const Vector3DFloat& pos) + { + float xIntPart; + float xFracPart = modf(pos.x(), &xIntPart); + float yIntPart; + float yFracPart = modf(pos.y(), &yIntPart); + float zIntPart; + float zFracPart = modf(pos.z(), &zIntPart); + + //Of all the fractional parts, two should be zero and one should have a value. + if(xFracPart > 0.000001f) + { + return vertexIndicesX[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; + } + if(yFracPart > 0.000001f) + { + return vertexIndicesY[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; + } + if(zFracPart > 0.000001f) + { + return vertexIndicesZ[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)]; + } + while(true); + } + + void IndexedSurfacePatch::setIndexFor(const Vector3DFloat& pos, boost::int32_t newIndex) + { + float xIntPart; + float xFracPart = modf(pos.x(), &xIntPart); + float yIntPart; + float yFracPart = modf(pos.y(), &yIntPart); + float zIntPart; + float zFracPart = modf(pos.z(), &zIntPart); + + //Of all the fractional parts, two should be zero and one should have a value. + if(xFracPart > 0.000001f) + { + vertexIndicesX[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; + } + if(yFracPart > 0.000001f) + { + vertexIndicesY[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; + } + if(zFracPart > 0.000001f) + { + vertexIndicesZ[static_cast(xIntPart)][static_cast(yIntPart)][static_cast(zIntPart)] = newIndex; + } + } } diff --git a/source/PolyVoxSceneManager.cpp b/source/PolyVoxSceneManager.cpp index 5b54d321..57524fed 100644 --- a/source/PolyVoxSceneManager.cpp +++ b/source/PolyVoxSceneManager.cpp @@ -238,8 +238,6 @@ namespace PolyVox void PolyVoxSceneManager::generateMeshDataForRegion(const uint16_t regionX, const uint16_t regionY, const uint16_t regionZ, IndexedSurfacePatch* singleMaterialPatch, IndexedSurfacePatch* multiMaterialPatch) const { - //IndexedSurfacePatch* surfacePatchResult = new IndexedSurfacePatch; - //First and last voxels in the region const uint16_t firstX = regionX * POLYVOX_REGION_SIDE_LENGTH; const uint16_t firstY = regionY * POLYVOX_REGION_SIDE_LENGTH; @@ -251,7 +249,7 @@ namespace PolyVox //Offset from lower block corner const Vector3DFloat offset(firstX,firstY,firstZ); - Vector3DUint32 vertlist[12]; + Vector3DFloat vertlist[12]; uint8_t vertMaterials[12]; VolumeIterator volIter(*volumeData); volIter.setValidRegion(firstX,firstY,firstZ,lastX,lastY,lastZ); @@ -299,100 +297,100 @@ namespace PolyVox /* Find the vertices where the surface intersects the cube */ if (edgeTable[iCubeIndex] & 1) { - vertlist[0].setX(2*x + 1); - vertlist[0].setY(2*y); - vertlist[0].setZ(2*z); + vertlist[0].setX(x + 0.5f); + vertlist[0].setY(y); + vertlist[0].setZ(z); vertMaterials[0] = v000 | v100; //Because one of these is 0, the or operation takes the max. } if (edgeTable[iCubeIndex] & 2) { - vertlist[1].setX(2*x + 2); - vertlist[1].setY(2*y + 1); - vertlist[1].setZ(2*z); + vertlist[1].setX(x + 1.0f); + vertlist[1].setY(y + 0.5f); + vertlist[1].setZ(z); vertMaterials[1] = v100 | v110; } if (edgeTable[iCubeIndex] & 4) { - vertlist[2].setX(2*x + 1); - vertlist[2].setY(2*y + 2); - vertlist[2].setZ(2*z); + vertlist[2].setX(x + 0.5f); + vertlist[2].setY(y + 1.0f); + vertlist[2].setZ(z); vertMaterials[2] = v010 | v110; } if (edgeTable[iCubeIndex] & 8) { - vertlist[3].setX(2*x); - vertlist[3].setY(2*y + 1); - vertlist[3].setZ(2*z); + vertlist[3].setX(x); + vertlist[3].setY(y + 0.5f); + vertlist[3].setZ(z); vertMaterials[3] = v000 | v010; } if (edgeTable[iCubeIndex] & 16) { - vertlist[4].setX(2*x + 1); - vertlist[4].setY(2*y); - vertlist[4].setZ(2*z + 2); + vertlist[4].setX(x + 0.5f); + vertlist[4].setY(y); + vertlist[4].setZ(z + 1.0f); vertMaterials[4] = v001 | v101; } if (edgeTable[iCubeIndex] & 32) { - vertlist[5].setX(2*x + 2); - vertlist[5].setY(2*y + 1); - vertlist[5].setZ(2*z + 2); + vertlist[5].setX(x + 1.0f); + vertlist[5].setY(y + 0.5f); + vertlist[5].setZ(z + 1.0f); vertMaterials[5] = v101 | v111; } if (edgeTable[iCubeIndex] & 64) { - vertlist[6].setX(2*x + 1); - vertlist[6].setY(2*y + 2); - vertlist[6].setZ(2*z + 2); + vertlist[6].setX(x + 0.5f); + vertlist[6].setY(y + 1.0f); + vertlist[6].setZ(z + 1.0f); vertMaterials[6] = v011 | v111; } if (edgeTable[iCubeIndex] & 128) { - vertlist[7].setX(2*x); - vertlist[7].setY(2*y + 1); - vertlist[7].setZ(2*z + 2); + vertlist[7].setX(x); + vertlist[7].setY(y + 0.5f); + vertlist[7].setZ(z + 1.0f); vertMaterials[7] = v001 | v011; } if (edgeTable[iCubeIndex] & 256) { - vertlist[8].setX(2*x); - vertlist[8].setY(2*y); - vertlist[8].setZ(2*z + 1); + vertlist[8].setX(x); + vertlist[8].setY(y); + vertlist[8].setZ(z + 0.5f); vertMaterials[8] = v000 | v001; } if (edgeTable[iCubeIndex] & 512) { - vertlist[9].setX(2*x + 2); - vertlist[9].setY(2*y); - vertlist[9].setZ(2*z + 1); + vertlist[9].setX(x + 1.0f); + vertlist[9].setY(y); + vertlist[9].setZ(z + 0.5f); vertMaterials[9] = v100 | v101; } if (edgeTable[iCubeIndex] & 1024) { - vertlist[10].setX(2*x + 2); - vertlist[10].setY(2*y + 2); - vertlist[10].setZ(2*z + 1); + vertlist[10].setX(x + 1.0f); + vertlist[10].setY(y + 1.0f); + vertlist[10].setZ(z + 0.5f); vertMaterials[10] = v110 | v111; } if (edgeTable[iCubeIndex] & 2048) { - vertlist[11].setX(2*x); - vertlist[11].setY(2*y + 2); - vertlist[11].setZ(2*z + 1); + vertlist[11].setX(x); + vertlist[11].setY(y + 1.0f); + vertlist[11].setZ(z + 0.5f); vertMaterials[11] = v010 | v011; } for (int i=0;triTable[iCubeIndex][i]!=-1;i+=3) { //The three vertices forming a triangle - const Vector3DUint32 vertex0 = vertlist[triTable[iCubeIndex][i ]]; - const Vector3DUint32 vertex1 = vertlist[triTable[iCubeIndex][i+1]]; - const Vector3DUint32 vertex2 = vertlist[triTable[iCubeIndex][i+2]]; + const Vector3DFloat vertex0 = vertlist[triTable[iCubeIndex][i ]] - offset; + const Vector3DFloat vertex1 = vertlist[triTable[iCubeIndex][i+1]] - offset; + const Vector3DFloat vertex2 = vertlist[triTable[iCubeIndex][i+2]] - offset; //Cast to floats and divide by two. - const Vector3DFloat vertex0AsFloat = (static_cast(vertex0) / 2.0f) - offset; - const Vector3DFloat vertex1AsFloat = (static_cast(vertex1) / 2.0f) - offset; - const Vector3DFloat vertex2AsFloat = (static_cast(vertex2) / 2.0f) - offset; + //const Vector3DFloat vertex0AsFloat = (static_cast(vertex0) / 2.0f) - offset; + //const Vector3DFloat vertex1AsFloat = (static_cast(vertex1) / 2.0f) - offset; + //const Vector3DFloat vertex2AsFloat = (static_cast(vertex2) / 2.0f) - offset; const uint8_t material0 = vertMaterials[triTable[iCubeIndex][i ]]; const uint8_t material1 = vertMaterials[triTable[iCubeIndex][i+1]]; @@ -402,79 +400,79 @@ namespace PolyVox //If all the materials are the same, we just need one triangle for that material with all the alphas set high. if((material0 == material1) && (material1 == material2)) { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material0 + 0.1,1.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material1 + 0.1,1.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material2 + 0.1,1.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material1 + 0.1,1.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material2 + 0.1,1.0); singleMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } else if(material0 == material1) { { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material0 + 0.1,1.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material0 + 0.1,1.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material0 + 0.1,0.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material0 + 0.1,0.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material2 + 0.1,0.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material2 + 0.1,0.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material2 + 0.1,1.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material2 + 0.1,0.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material2 + 0.1,0.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material2 + 0.1,1.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } } else if(material0 == material2) { { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material0 + 0.1,1.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material0 + 0.1,0.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material0 + 0.1,0.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material0 + 0.1,1.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material1 + 0.1,0.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material1 + 0.1,1.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material1 + 0.1,0.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material1 + 0.1,0.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material1 + 0.1,1.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material1 + 0.1,0.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } } else if(material1 == material2) { { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material1 + 0.1,0.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material1 + 0.1,1.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material1 + 0.1,1.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material1 + 0.1,0.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material1 + 0.1,1.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material1 + 0.1,1.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material0 + 0.1,1.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material0 + 0.1,0.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material0 + 0.1,0.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material0 + 0.1,0.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material0 + 0.1,0.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } } else { { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material0 + 0.1,1.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material0 + 0.1,0.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material0 + 0.1,0.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material0 + 0.1,1.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material0 + 0.1,0.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material0 + 0.1,0.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material1 + 0.1,0.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material1 + 0.1,1.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material1 + 0.1,0.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material1 + 0.1,0.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material1 + 0.1,1.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material1 + 0.1,0.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } { - SurfaceVertex surfaceVertex0Alpha1(vertex0AsFloat,material2 + 0.1,0.0); - SurfaceVertex surfaceVertex1Alpha1(vertex1AsFloat,material2 + 0.1,0.0); - SurfaceVertex surfaceVertex2Alpha1(vertex2AsFloat,material2 + 0.1,1.0); + SurfaceVertex surfaceVertex0Alpha1(vertex0,material2 + 0.1,0.0); + SurfaceVertex surfaceVertex1Alpha1(vertex1,material2 + 0.1,0.0); + SurfaceVertex surfaceVertex2Alpha1(vertex2,material2 + 0.1,1.0); multiMaterialPatch->addTriangle(surfaceVertex0Alpha1, surfaceVertex1Alpha1, surfaceVertex2Alpha1); } }