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;