Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PolyVoxCore/MeshDecimator.h"
00025 #include "PolyVoxCore/SurfaceMesh.h"
00026
00027 using namespace std;
00028
00029 namespace PolyVox
00030 {
00031 template<>
00032 POLYVOX_API void MeshDecimator<PositionMaterial>::fillInitialVertexMetadata(std::vector<InitialVertexMetadata>& vecVertexMetadata)
00033 {
00034 vecVertexMetadata.clear();
00035 vecVertexMetadata.resize(m_pOutputMesh->m_vecVertices.size());
00036
00037 for(uint32_t ct = 0; ct < vecVertexMetadata.size(); ct++)
00038 {
00039 vecVertexMetadata[ct].normal.setElements(0,0,0);
00040 vecVertexMetadata[ct].isOnMaterialEdge = false;
00041 vecVertexMetadata[ct].isOnRegionFace.reset();
00042 }
00043
00044
00045
00046
00047 std::vector<IntVertex> intVertices;
00048 intVertices.reserve(m_pOutputMesh->m_vecVertices.size());
00049 for(uint32_t ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
00050 {
00051 const Vector3DFloat& floatPos = m_pOutputMesh->m_vecVertices[ct].position;
00052 IntVertex intVertex(static_cast<uint32_t>(floatPos.getX()), static_cast<uint32_t>(floatPos.getY()), static_cast<uint32_t>(floatPos.getZ()), ct);
00053 intVertices.push_back(intVertex);
00054 }
00055
00056
00057 sort(intVertices.begin(), intVertices.end());
00058
00059
00060 for(uint32_t ct = 0; ct < intVertices.size() - 1; ct++)
00061 {
00062 const IntVertex& v0 = intVertices[ct+0];
00063 const IntVertex& v1 = intVertices[ct+1];
00064
00065 if((v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z))
00066 {
00067 vecVertexMetadata[v0.index].isOnMaterialEdge = true;
00068 vecVertexMetadata[v1.index].isOnMaterialEdge = true;
00069 }
00070 }
00071
00072
00073 for(uint32_t ct = 0; ct < m_pOutputMesh->m_vecVertices.size(); ct++)
00074 {
00075 Vector3DFloat sumOfNormals(0.0f,0.0f,0.0f);
00076 for(vector<uint32_t>::iterator iter = trianglesUsingVertex[ct].begin(); iter != trianglesUsingVertex[ct].end(); iter++)
00077 {
00078 sumOfNormals += m_vecTriangles[*iter].normal;
00079 }
00080
00081 vecVertexMetadata[ct].normal = sumOfNormals;
00082 vecVertexMetadata[ct].normal.normalise();
00083 }
00084
00085
00086 for(uint32_t ct = 0; ct < vecVertexMetadata.size(); ct++)
00087 {
00088 Region regTransformed = m_pOutputMesh->m_Region;
00089 regTransformed.shift(regTransformed.getLowerCorner() * static_cast<int32_t>(-1));
00090
00091
00092 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() < regTransformed.getLowerCorner().getX() + 0.001f);
00093 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() > regTransformed.getUpperCorner().getX() - 0.001f);
00094
00095 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() < regTransformed.getLowerCorner().getY() + 0.001f);
00096 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() > regTransformed.getUpperCorner().getY() - 0.001f);
00097
00098 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() < regTransformed.getLowerCorner().getZ() + 0.001f);
00099 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() > regTransformed.getUpperCorner().getZ() - 0.001f);
00100 }
00101 }
00102
00103 template<>
00104 POLYVOX_API void MeshDecimator<PositionMaterialNormal>::fillInitialVertexMetadata(std::vector<InitialVertexMetadata>& vecVertexMetadata)
00105 {
00106 vecVertexMetadata.clear();
00107 vecVertexMetadata.resize(m_pOutputMesh->m_vecVertices.size());
00108
00109
00110 for(uint32_t ct = 0; ct < vecVertexMetadata.size(); ct++)
00111 {
00112 vecVertexMetadata[ct].isOnRegionFace.reset();
00113 vecVertexMetadata[ct].isOnMaterialEdge = false;
00114 vecVertexMetadata[ct].normal = m_pOutputMesh->m_vecVertices[ct].normal;
00115 }
00116
00117
00118 for(uint32_t ct = 0; ct < vecVertexMetadata.size(); ct++)
00119 {
00120 Region regTransformed = m_pOutputMesh->m_Region;
00121 regTransformed.shift(regTransformed.getLowerCorner() * static_cast<int32_t>(-1));
00122
00123
00124 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() < regTransformed.getLowerCorner().getX() + 0.001f);
00125 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_X, m_pOutputMesh->m_vecVertices[ct].getPosition().getX() > regTransformed.getUpperCorner().getX() - 0.001f);
00126
00127 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() < regTransformed.getLowerCorner().getY() + 0.001f);
00128 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Y, m_pOutputMesh->m_vecVertices[ct].getPosition().getY() > regTransformed.getUpperCorner().getY() - 0.001f);
00129
00130 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_NEG_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() < regTransformed.getLowerCorner().getZ() + 0.001f);
00131 vecVertexMetadata[ct].isOnRegionFace.set(RFF_ON_REGION_FACE_POS_Z, m_pOutputMesh->m_vecVertices[ct].getPosition().getZ() > regTransformed.getUpperCorner().getZ() - 0.001f);
00132 }
00133
00134
00135
00136
00137 for(uint32_t ct = 0; ct < m_vecTriangles.size(); ct++)
00138 {
00139 uint32_t v0 = m_vecTriangles[ct].v0;
00140 uint32_t v1 = m_vecTriangles[ct].v1;
00141 uint32_t v2 = m_vecTriangles[ct].v2;
00142
00143 bool allMatch =
00144 (m_pOutputMesh->m_vecVertices[v0].material == m_pOutputMesh->m_vecVertices[v1].material) &&
00145 (m_pOutputMesh->m_vecVertices[v1].material == m_pOutputMesh->m_vecVertices[v2].material);
00146
00147 if(!allMatch)
00148 {
00149 vecVertexMetadata[v0].isOnMaterialEdge = true;
00150 vecVertexMetadata[v1].isOnMaterialEdge = true;
00151 vecVertexMetadata[v2].isOnMaterialEdge = true;
00152 }
00153 }
00154 }
00155
00156 template<>
00157 POLYVOX_API bool MeshDecimator<PositionMaterialNormal>::canCollapseNormalEdge(uint32_t uSrc, uint32_t uDst)
00158 {
00159 if(m_vecInitialVertexMetadata[uSrc].normal.dot(m_vecInitialVertexMetadata[uDst].normal) < m_fMinDotProductForCollapse)
00160 {
00161 return false;
00162 }
00163
00164
00165 return !collapseChangesFaceNormals(uSrc, uDst, m_fMinDotProductForCollapse);
00166 }
00167
00168 template<>
00169 POLYVOX_API bool MeshDecimator<PositionMaterial>::canCollapseNormalEdge(uint32_t uSrc, uint32_t uDst)
00170 {
00171
00172
00173
00174
00175
00176
00177
00178
00179 return !collapseChangesFaceNormals(uSrc, uDst, 0.999f);
00180 }
00181 }