34 template<
typename VolumeType,
typename IsQuadNeeded>
35 const uint32_t CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::MaxVerticesPerPosition = 6;
37 template<
typename VolumeType,
typename IsQuadNeeded>
40 ,m_regSizeInVoxels(region)
41 ,m_meshCurrent(result)
42 ,m_bMergeQuads(bMergeQuads)
44 m_funcIsQuadNeededCallback = isQuadNeeded;
47 template<
typename VolumeType,
typename IsQuadNeeded>
50 m_meshCurrent->clear();
52 uint32_t uArrayWidth = m_regSizeInVoxels.getUpperCorner().getX() - m_regSizeInVoxels.getLowerCorner().getX() + 2;
53 uint32_t uArrayHeight = m_regSizeInVoxels.getUpperCorner().getY() - m_regSizeInVoxels.getLowerCorner().getY() + 2;
55 uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition};
56 m_previousSliceVertices.resize(arraySize);
57 m_currentSliceVertices.resize(arraySize);
58 memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.getNoOfElements() *
sizeof(IndexAndMaterial));
59 memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() *
sizeof(IndexAndMaterial));
61 m_vecQuads[NegativeX].resize(m_regSizeInVoxels.getUpperCorner().getX() - m_regSizeInVoxels.getLowerCorner().getX() + 2);
62 m_vecQuads[PositiveX].resize(m_regSizeInVoxels.getUpperCorner().getX() - m_regSizeInVoxels.getLowerCorner().getX() + 2);
64 m_vecQuads[NegativeY].resize(m_regSizeInVoxels.getUpperCorner().getY() - m_regSizeInVoxels.getLowerCorner().getY() + 2);
65 m_vecQuads[PositiveY].resize(m_regSizeInVoxels.getUpperCorner().getY() - m_regSizeInVoxels.getLowerCorner().getY() + 2);
67 m_vecQuads[NegativeZ].resize(m_regSizeInVoxels.getUpperCorner().getZ() - m_regSizeInVoxels.getLowerCorner().getZ() + 2);
68 m_vecQuads[PositiveZ].resize(m_regSizeInVoxels.getUpperCorner().getZ() - m_regSizeInVoxels.getLowerCorner().getZ() + 2);
70 typename VolumeType::Sampler volumeSampler(m_volData);
72 for(
int32_t z = m_regSizeInVoxels.getLowerCorner().getZ(); z <= m_regSizeInVoxels.getUpperCorner().getZ(); z++)
74 uint32_t regZ = z - m_regSizeInVoxels.getLowerCorner().getZ();
76 for(
int32_t y = m_regSizeInVoxels.getLowerCorner().getY(); y <= m_regSizeInVoxels.getUpperCorner().getY(); y++)
78 uint32_t regY = y - m_regSizeInVoxels.getLowerCorner().getY();
80 for(
int32_t x = m_regSizeInVoxels.getLowerCorner().getX(); x <= m_regSizeInVoxels.getUpperCorner().getX(); x++)
82 uint32_t regX = x - m_regSizeInVoxels.getLowerCorner().getX();
84 volumeSampler.setPosition(x,y,z);
87 typename VolumeType::VoxelType currentVoxel = volumeSampler.getVoxel();
88 typename VolumeType::VoxelType negXVoxel = volumeSampler.peekVoxel1nx0py0pz();
89 typename VolumeType::VoxelType negYVoxel = volumeSampler.peekVoxel0px1ny0pz();
90 typename VolumeType::VoxelType negZVoxel = volumeSampler.peekVoxel0px0py1nz();
93 if(m_funcIsQuadNeededCallback(currentVoxel, negXVoxel, material))
95 uint32_t v0 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
96 uint32_t v1 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
97 uint32_t v2 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
98 uint32_t v3 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
100 m_vecQuads[NegativeX][regX].push_back(Quad(v0, v1, v2, v3));
103 if(m_funcIsQuadNeededCallback(negXVoxel, currentVoxel, material))
105 uint32_t v0 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
106 uint32_t v1 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
107 uint32_t v2 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
108 uint32_t v3 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
110 m_vecQuads[PositiveX][regX].push_back(Quad(v0, v3, v2, v1));
114 if(m_funcIsQuadNeededCallback(currentVoxel, negYVoxel, material))
116 uint32_t v0 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
117 uint32_t v1 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
118 uint32_t v2 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
119 uint32_t v3 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
121 m_vecQuads[NegativeY][regY].push_back(Quad(v0, v1, v2, v3));
124 if(m_funcIsQuadNeededCallback(negYVoxel, currentVoxel, material))
126 uint32_t v0 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
127 uint32_t v1 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
128 uint32_t v2 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
129 uint32_t v3 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) + 0.5f, material, m_currentSliceVertices);
131 m_vecQuads[PositiveY][regY].push_back(Quad(v0, v3, v2, v1));
135 if(m_funcIsQuadNeededCallback(currentVoxel, negZVoxel, material))
137 uint32_t v0 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
138 uint32_t v1 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
139 uint32_t v2 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
140 uint32_t v3 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
142 m_vecQuads[NegativeZ][regZ].push_back(Quad(v0, v1, v2, v3));
145 if(m_funcIsQuadNeededCallback(negZVoxel, currentVoxel, material))
147 uint32_t v0 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
148 uint32_t v1 = addVertex(static_cast<float>(regX) - 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
149 uint32_t v2 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) + 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
150 uint32_t v3 = addVertex(static_cast<float>(regX) + 0.5f, static_cast<float>(regY) - 0.5f, static_cast<float>(regZ) - 0.5f, material, m_previousSliceVertices);
152 m_vecQuads[PositiveZ][regZ].push_back(Quad(v0, v3, v2, v1));
157 m_previousSliceVertices.swap(m_currentSliceVertices);
158 memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() *
sizeof(IndexAndMaterial));
161 for(uint32_t uFace = 0; uFace < NoOfFaces; uFace++)
163 std::vector< std::list<Quad> >& vecListQuads = m_vecQuads[uFace];
165 for(uint32_t slice = 0; slice < vecListQuads.size(); slice++)
167 std::list<Quad>& listQuads = vecListQuads[slice];
173 while(performQuadMerging(listQuads)){}
176 typename std::list<Quad>::iterator iterEnd = listQuads.end();
177 for(
typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
179 Quad& quad = *quadIter;
180 m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[1],quad.vertices[2]);
181 m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[2],quad.vertices[3]);
186 m_meshCurrent->m_Region = m_regSizeInVoxels;
187 m_meshCurrent->removeUnusedVertices();
189 m_meshCurrent->m_vecLodRecords.clear();
192 lodRecord.
endIndex = m_meshCurrent->getNoOfIndices();
193 m_meshCurrent->m_vecLodRecords.push_back(lodRecord);
196 template<
typename VolumeType,
typename IsQuadNeeded>
199 uint32_t uX =
static_cast<uint32_t
>(fX + 0.75f);
200 uint32_t uY =
static_cast<uint32_t
>(fY + 0.75f);
202 for(uint32_t ct = 0; ct < MaxVerticesPerPosition; ct++)
204 IndexAndMaterial& rEntry = existingVertices[uX][uY][ct];
206 if(rEntry.iIndex == -1)
210 rEntry.uMaterial = uMaterialIn;
212 return rEntry.iIndex;
216 if(rEntry.uMaterial == static_cast<int32_t>(uMaterialIn))
218 return rEntry.iIndex;
228 template<
typename VolumeType,
typename IsQuadNeeded>
229 bool CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::performQuadMerging(std::list<Quad>& quads)
231 bool bDidMerge =
false;
232 for(
typename std::list<Quad>::iterator outerIter = quads.begin(); outerIter != quads.end(); outerIter++)
234 typename std::list<Quad>::iterator innerIter = outerIter;
236 while(innerIter != quads.end())
238 Quad& q1 = *outerIter;
239 Quad& q2 = *innerIter;
241 bool result = mergeQuads(q1,q2);
246 innerIter = quads.erase(innerIter);
258 template<
typename VolumeType,
typename IsQuadNeeded>
259 bool CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::mergeQuads(Quad& q1, Quad& q2)
263 if(std::abs(m_meshCurrent->getVertices()[q1.vertices[0]].getMaterial() - m_meshCurrent->getVertices()[q2.vertices[0]].getMaterial()) < 0.001)
268 if((q1.vertices[0] == q2.vertices[1]) && ((q1.vertices[3] == q2.vertices[2])))
270 q1.vertices[0] = q2.vertices[0];
271 q1.vertices[3] = q2.vertices[3];
274 else if((q1.vertices[3] == q2.vertices[0]) && ((q1.vertices[2] == q2.vertices[1])))
276 q1.vertices[3] = q2.vertices[3];
277 q1.vertices[2] = q2.vertices[2];
280 else if((q1.vertices[1] == q2.vertices[0]) && ((q1.vertices[2] == q2.vertices[3])))
282 q1.vertices[1] = q2.vertices[1];
283 q1.vertices[2] = q2.vertices[2];
286 else if((q1.vertices[0] == q2.vertices[3]) && ((q1.vertices[1] == q2.vertices[2])))
288 q1.vertices[0] = q2.vertices[0];
289 q1.vertices[1] = q2.vertices[1];