42 #include <boost/filesystem.hpp>
51 std::shared_ptr<std::vector<T>> arr_;
54 explicit VectorCapsule(std::vector<T>&& arr)
55 : arr_(
std::make_shared<
std::vector<T>>(
std::move(arr)))
58 ~VectorCapsule() =
default;
59 void operator()(
void*) {}
68 float maxChunkOverlap,
76 std::vector<std::string>{layer},
82 float maxChunkOverlap,
84 std::vector<std::string> layers,
89 if (meshes.size() != layers.size())
91 std::cerr <<
lvr2::timestamp <<
"Number of meshes and layers do not match: \n"
92 <<
"Num meshes: " << meshes.size() <<
"\n"
93 <<
"Num layers: " << layers.size() << std::endl;
99 for (
size_t i = 0; i < meshes.size(); ++i)
104 for (
size_t i = 0; i < meshes.size(); ++i)
106 buildChunks(meshes[i], maxChunkOverlap, savePath, layers[i]);
117 std::vector<std::string> attributeList;
120 bool isChunkFound =
false;
128 boost::optional<MeshBufferPtr> requestedChunk
129 = getChunk<MeshBufferPtr>(layer, x, y, z);
132 chunkPtr = requestedChunk.get();
141 for (
auto channelIterator = chunkPtr->begin(); channelIterator != chunkPtr->end();
144 attributeList.push_back(channelIterator->first);
147 return attributeList;
151 std::unordered_map<std::size_t, MeshBufferPtr>& chunks,
156 adjustedAreaMax[0] = std::min(area.getMax()[0],
getBoundingBox().getMax()[0]);
157 adjustedAreaMax[1] = std::min(area.getMax()[1],
getBoundingBox().getMax()[1]);
158 adjustedAreaMax[2] = std::min(area.getMax()[2],
getBoundingBox().getMax()[2]);
159 adjustedAreaMin[0] = std::max(area.getMin()[0],
getBoundingBox().getMin()[0]);
160 adjustedAreaMin[1] = std::max(area.getMin()[1],
getBoundingBox().getMin()[1]);
161 adjustedAreaMin[2] = std::max(area.getMin()[2],
getBoundingBox().getMin()[2]);
169 for (std::size_t i = 0; i < maxSteps.x; ++i)
171 for (std::size_t j = 0; j < maxSteps.y; ++j)
173 for (std::size_t k = 0; k < maxSteps.z; ++k)
177 size_t cellIndex =
hashValue(cellCoord.
x, cellCoord.
y, cellCoord.
z);
185 boost::optional<MeshBufferPtr> loadedChunk
186 = getChunk<MeshBufferPtr>(layer, cellCoord.
x, cellCoord.
y, cellCoord.
z);
193 chunks.insert({cellIndex, *loadedChunk});
204 std::unordered_map<std::size_t, MeshBufferPtr> chunks;
208 adjustedAreaMax[0] = std::min(area.getMax()[0],
getBoundingBox().getMax()[0]);
209 adjustedAreaMax[1] = std::min(area.getMax()[1],
getBoundingBox().getMax()[1]);
210 adjustedAreaMax[2] = std::min(area.getMax()[2],
getBoundingBox().getMax()[2]);
211 adjustedAreaMin[0] = std::max(area.getMin()[0],
getBoundingBox().getMin()[0]);
212 adjustedAreaMin[1] = std::max(area.getMin()[1],
getBoundingBox().getMin()[1]);
213 adjustedAreaMin[2] = std::max(area.getMin()[2],
getBoundingBox().getMin()[2]);
221 for (std::size_t i = 0; i < maxSteps.x; ++i)
223 for (std::size_t j = 0; j < maxSteps.y; ++j)
225 for (std::size_t k = 0; k < maxSteps.z; ++k)
229 size_t cellIndex =
hashValue(cellCoord.
x, cellCoord.
y, cellCoord.
z);
231 boost::optional<MeshBufferPtr> loadedChunk
232 = getChunk<MeshBufferPtr>(layer, cellCoord.
x, cellCoord.
y, cellCoord.
z);
237 "area/" + std::to_string(cellIndex) +
".ply");
238 chunks.insert({cellIndex, *loadedChunk});
243 std::cout <<
"Extracted " << chunks.size() <<
" Chunks" << std::endl;
245 std::vector<float> areaDuplicateVertices;
246 std::vector<std::unordered_map<std::size_t, std::size_t>> areaVertexIndices;
247 std::vector<float> areaUniqueVertices;
248 for (
auto chunkIt = chunks.begin(); chunkIt != chunks.end(); ++chunkIt)
251 FloatChannel chunkVertices = *(chunk->getChannel<
float>(
"vertices"));
252 std::size_t numDuplicates = *chunk->getAtomic<
unsigned int>(
"num_duplicates");
253 std::size_t numVertices = chunk->numVertices();
254 std::unordered_map<std::size_t, std::size_t> chunkVertexIndices;
256 if (numVertices == 0)
261 if ((chunkIt == chunks.begin() || areaDuplicateVertices.empty()) && numDuplicates > 0)
263 areaDuplicateVertices.insert(areaDuplicateVertices.end(),
265 chunkVertices.
dataPtr().get() + (numDuplicates * 3));
268 for (std::size_t i = 0; i < numDuplicates; ++i)
270 const size_t areaDuplicateVerticesSize = areaDuplicateVertices.size();
273 for (std::size_t j = 0; j < areaDuplicateVerticesSize / 3; ++j)
275 if ((areaDuplicateVertices[j * 3] == chunkVertices[i][0])
276 && (areaDuplicateVertices[j * 3 + 1] == chunkVertices[i][1])
277 && (areaDuplicateVertices[j * 3 + 2] == chunkVertices[i][2]))
280 chunkVertexIndices.insert({i, j});
287 areaDuplicateVertices.push_back(chunkVertices[i][0]);
288 areaDuplicateVertices.push_back(chunkVertices[i][1]);
289 areaDuplicateVertices.push_back(chunkVertices[i][2]);
291 chunkVertexIndices.insert({i, areaDuplicateVertices.size() / 3 - 1});
295 areaUniqueVertices.insert(areaUniqueVertices.end(),
296 chunkVertices.
dataPtr().get() + (numDuplicates * 3),
297 (chunkVertices.
dataPtr().get() + (numVertices * 3)));
299 areaVertexIndices.push_back(chunkVertexIndices);
302 std::vector<unsigned int> areaFaceIndices;
303 const std::size_t staticFaceIndexOffset = areaDuplicateVertices.size() / 3;
304 std::size_t dynFaceIndexOffset = 0;
305 auto areaVertexIndicesIt = areaVertexIndices.begin();
306 for (
auto chunkIt = chunks.begin(); chunkIt != chunks.end(); ++chunkIt)
309 indexArray chunkFaceIndices = chunk->getFaceIndices();
310 std::size_t numDuplicates = *chunk->getAtomic<
unsigned int>(
"num_duplicates");
311 std::size_t numVertices = chunk->numVertices();
312 std::size_t numFaces = chunk->numFaces();
313 std::size_t faceIndexOffset = staticFaceIndexOffset - numDuplicates + dynFaceIndexOffset;
315 for (std::size_t i = 0; i < numFaces * 3; ++i)
317 std::size_t oldIndex = chunkFaceIndices[i];
318 auto it = (*areaVertexIndicesIt).find(oldIndex);
319 if (it != (*areaVertexIndicesIt).end())
321 areaFaceIndices.push_back(it->second);
325 areaFaceIndices.push_back(oldIndex + faceIndexOffset);
328 dynFaceIndexOffset += (numVertices - numDuplicates);
329 ++areaVertexIndicesIt;
332 std::cout <<
"combine vertices" << std::endl;
333 std::cout <<
"Duplicates: " << areaDuplicateVertices.size() / 3 << std::endl;
334 std::cout <<
"Unique: " << areaUniqueVertices.size() / 3 << std::endl;
335 areaDuplicateVertices.insert(
336 areaDuplicateVertices.end(), areaUniqueVertices.begin(), areaUniqueVertices.end());
338 std::size_t areaVertexNum = areaDuplicateVertices.size() / 3;
339 float* tmpVertices = areaDuplicateVertices.data();
341 =
floatArr(tmpVertices, VectorCapsule<float>(std::move(areaDuplicateVertices)));
343 std::size_t faceIndexNum = areaFaceIndices.size() / 3;
344 auto* tmpFaceIndices = areaFaceIndices.data();
346 =
indexArray(tmpFaceIndices, VectorCapsule<unsigned int>(std::move(areaFaceIndices)));
349 areaMeshPtr->setVertices(vertexArr, areaVertexNum);
350 areaMeshPtr->setFaceIndices(faceIndexArr, faceIndexNum);
352 for (
auto chunkIt = chunks.begin(); chunkIt != chunks.end(); ++chunkIt)
355 for (
auto elem : *chunk)
357 if (elem.first !=
"vertices" && elem.first !=
"face_indices"
358 && elem.first !=
"num_duplicates")
360 if (areaMeshPtr->find(elem.first) == areaMeshPtr->end())
363 if (elem.second.is_type<
unsigned char>())
365 areaMeshPtr->template addChannel<unsigned char>(
366 extractChannelOfArea<unsigned char>(chunks,
368 staticFaceIndexOffset,
369 areaMeshPtr->numVertices(),
370 areaMeshPtr->numFaces(),
374 else if (elem.second.is_type<
unsigned int>())
376 areaMeshPtr->template addChannel<unsigned int>(
377 extractChannelOfArea<unsigned int>(chunks,
379 staticFaceIndexOffset,
380 areaMeshPtr->numVertices(),
381 areaMeshPtr->numFaces(),
385 else if (elem.second.is_type<
float>())
387 areaMeshPtr->template addChannel<float>(
388 extractChannelOfArea<float>(chunks,
390 staticFaceIndexOffset,
391 areaMeshPtr->numVertices(),
392 areaMeshPtr->numFaces(),
401 std::cout <<
"Vertices: " << areaMeshPtr->numVertices()
402 <<
", Faces: " << areaMeshPtr->numFaces() << std::endl;
410 const std::map<std::string, FilterFunction>
filter,
417 std::vector<bool> vertexFilter(areaMesh->numVertices(),
true);
418 std::vector<bool> faceFilter(areaMesh->numFaces(),
true);
419 std::size_t numVertices = areaMesh->numVertices();
420 std::size_t numFaces = areaMesh->numFaces();
422 for (
auto channelFilter :
filter)
424 if (areaMesh->find(channelFilter.first) != areaMesh->end())
427 #pragma omp parallel for
428 for (std::size_t i = 0; i < channel.
numElements(); i++)
430 if (channel.
numElements() == areaMesh->numVertices())
432 if (vertexFilter[i] ==
true)
434 vertexFilter[i] = channelFilter.second(channel, i);
435 if (vertexFilter[i] ==
false)
441 else if (channel.
numElements() == areaMesh->numFaces())
443 if (faceFilter[i] ==
true)
445 faceFilter[i] = channelFilter.second(channel, i);
446 if (faceFilter[i] ==
false)
457 IndexChannel facesChannel = *areaMesh->getIndexChannel(
"face_indices");
458 for (std::size_t i = 0; i < areaMesh->numFaces(); i++)
460 if (faceFilter[i] ==
true)
462 for (std::size_t j = 0; j < facesChannel.
width(); j++)
464 if (vertexFilter[facesChannel[i][j]] ==
false)
466 faceFilter[i] =
false;
475 std::vector<std::size_t> vertexIndexMapping(areaMesh->numVertices(), 0);
476 std::size_t tmpIndex = 0;
477 for (std::size_t i = 0; i < areaMesh->numVertices(); i++)
479 if (vertexFilter[i] ==
true)
481 vertexIndexMapping[i] = tmpIndex;
489 for (
auto& channel : *areaMesh)
493 if (channel.second.is_type<
unsigned char>())
495 channel.second = applyChannelFilter<unsigned char>(
496 vertexFilter, faceFilter, numVertices, numFaces, areaMesh, channel.second);
498 else if (channel.second.is_type<
unsigned int>())
500 channel.second = applyChannelFilter<unsigned int>(
501 vertexFilter, faceFilter, numVertices, numFaces, areaMesh, channel.second);
503 else if (channel.second.is_type<
float>())
505 channel.second = applyChannelFilter<float>(
506 vertexFilter, faceFilter, numVertices, numFaces, areaMesh, channel.second);
513 facesChannel = *areaMesh->getIndexChannel(
"face_indices");
514 for (std::size_t i = 0; i < areaMesh->numFaces(); i++)
516 for (std::size_t j = 0; j < facesChannel.
width(); j++)
518 facesChannel[i][j] = vertexIndexMapping[facesChannel[i][j]];
529 for (
unsigned int i = 0; i < vertices.
numElements(); i++)
539 std::shared_ptr<std::unordered_map<unsigned int, unsigned int>> splitVertices,
540 std::shared_ptr<std::unordered_map<unsigned int, unsigned int>> splitFaces)
545 while (iterator != halfEdgeMesh->edgesEnd())
548 std::array<VertexHandle, 2> vertices = halfEdgeMesh->getVerticesOfEdge(*iterator);
549 for (
unsigned int i = 0; i <= 1; i++)
554 bool isLargeEdge =
false;
557 for (
unsigned int axis = 0; axis < 3; axis++)
560 float referenceVertexKey = halfEdgeMesh->getVertexPosition(referenceVertex)[axis];
561 float comparedVertexKey = halfEdgeMesh->getVertexPosition(comparedVertex)[axis];
565 if (fabs(referenceVertexKey - comparedVertexKey) > 2 *
getChunkSize())
578 if (referenceVertexKey < comparedVertexKey)
584 if (referenceVertexKey - chunkBorder < 0 && comparedVertexKey - chunkBorder >= 0
585 && chunkBorder - referenceVertexKey > overlapRatio *
getChunkSize()
586 && comparedVertexKey - chunkBorder > overlapRatio *
getChunkSize())
591 else if (referenceVertexKey - chunkBorder >= 0
592 && comparedVertexKey - chunkBorder < 0
593 && referenceVertexKey - chunkBorder > overlapRatio *
getChunkSize()
594 && chunkBorder - comparedVertexKey > overlapRatio *
getChunkSize())
603 std::array<OptionalFaceHandle, 2> faces = halfEdgeMesh->getFacesOfEdge(*iterator);
606 unsigned int faceIndex = halfEdgeMesh->nextFaceIndex();
609 unsigned int face = faces[0].unwrap().idx();
610 while (splitFaces->find(face) != splitFaces->end())
612 face = splitFaces->at(face);
614 splitFaces->insert({faceIndex, face});
619 unsigned int face = faces[1].unwrap().idx();
620 while (splitFaces->find(face) != splitFaces->end())
622 face = splitFaces->at(face);
624 splitFaces->insert({faceIndex, face});
627 unsigned int vertex = referenceVertex.
idx();
628 while (splitVertices->find(vertex) != splitVertices->end())
630 vertex = splitVertices->at(vertex);
632 splitVertices->insert({halfEdgeMesh->nextVertexIndex(), vertex});
635 float cutRatio = 0.5;
637 = halfEdgeMesh->getVertexPosition(referenceVertex) * cutRatio
638 + halfEdgeMesh->getVertexPosition(comparedVertex) * (1 - cutRatio);
640 halfEdgeMesh->splitVertex(*iterator,
642 halfEdgeMesh->getVertexPosition(referenceVertex),
653 float maxChunkOverlap,
654 std::string savePath,
660 std::shared_ptr<HalfEdgeMesh<BaseVector<float>>> halfEdgeMesh
661 = std::shared_ptr<HalfEdgeMesh<BaseVector<float>>>(
665 std::shared_ptr<std::unordered_map<unsigned int, unsigned int>> splitVertices(
666 new std::unordered_map<unsigned int, unsigned int>);
667 std::shared_ptr<std::unordered_map<unsigned int, unsigned int>> splitFaces(
668 new std::unordered_map<unsigned int, unsigned int>);
671 cutLargeFaces(halfEdgeMesh, maxChunkOverlap, splitVertices, splitFaces);
674 std::shared_ptr<std::unordered_map<unsigned int, std::vector<std::weak_ptr<ChunkBuilder>>>>
675 vertexUse(
new std::unordered_map<
unsigned int, std::vector<std::weak_ptr<ChunkBuilder>>>());
692 for (
size_t i = 0; i < halfEdgeMesh->numFaces(); i++)
696 size_t hash =
hashValue(cellCorrdinate.
x, cellCorrdinate.
y, cellCorrdinate.
z);
698 chunkBuilders[hash]->addFace(*iterator);
712 if (chunkBuilders[hash]->numFaces() > 0)
718 = chunkBuilders[hash]->buildMesh(
mesh, splitVertices, splitFaces);
726 setChunk<MeshBufferPtr>(layer, i, j, k, chunkMeshPtr);
728 chunkBuilders[hash] =
nullptr;
738 return (
mesh->getVertexPositionsOfFace(handle)[0] +
mesh->getVertexPositionsOfFace(handle)[1]
739 +
mesh->getVertexPositionsOfFace(handle)[2])
747 static_cast<int>(tmpVec.
x),
static_cast<int>(tmpVec.
y),
static_cast<int>(tmpVec.
z));
768 if (loadChunk<MeshBufferPtr>(layer, i, j, k))
776 std::cout <<
"loaded " << numLoaded <<
" chunks from hdf5-file." << std::endl;