RepoNode RepoNode::cloneAndRemoveParent( const repoUUID &parentID, const bool &newUniqueID) const { RepoBSONBuilder builder; RepoBSONBuilder arrayBuilder; std::vector<repoUUID> currentParents = getParentIDs(); auto parentIdx = std::find(currentParents.begin(), currentParents.end(), parentID); if (parentIdx != currentParents.end()) { currentParents.erase(parentIdx); if (newUniqueID) { builder.append(REPO_NODE_LABEL_ID, generateUUID()); } } else { repoWarning << "Trying to remove a parent that isn't really a parent!"; } if (currentParents.size() > 0) { builder.appendArray(REPO_NODE_LABEL_PARENTS, currentParents); builder.appendElementsUnique(*this); } else { builder.appendElementsUnique(removeField(REPO_NODE_LABEL_PARENTS)); } return RepoNode(builder.obj(), bigFiles); }
RepoNode RepoNode::cloneAndAddParent( const repoUUID &parentID, const bool &newUniqueID, const bool &newSharedID, const bool &overwrite) const { RepoBSONBuilder builder; RepoBSONBuilder arrayBuilder; std::vector<repoUUID> currentParents; if (!overwrite) { currentParents = getParentIDs(); } if (std::find(currentParents.begin(), currentParents.end(), parentID) == currentParents.end()) currentParents.push_back(parentID); builder.appendArray(REPO_NODE_LABEL_PARENTS, currentParents); if (newUniqueID) builder.append(REPO_NODE_LABEL_ID, generateUUID()); if (newSharedID) builder.append(REPO_NODE_LABEL_SHARED_ID, generateUUID()); builder.appendElementsUnique(*this); return RepoNode(builder.obj(), bigFiles); }
RepoNode RepoNode::cloneAndAddFields( const RepoBSON *changes, const bool &newUniqueID) const { RepoBSONBuilder builder; if (newUniqueID) { builder.append(REPO_NODE_LABEL_ID, generateUUID()); } builder.appendElementsUnique(*changes); builder.appendElementsUnique(*this); return RepoNode(builder.obj(), bigFiles); }
RepoNode CameraNode::cloneAndApplyTransformation( const std::vector<float> &matrix) const { RepoBSONBuilder builder; if (hasField(REPO_NODE_LABEL_LOOK_AT)) { builder.append(REPO_NODE_LABEL_LOOK_AT, multiplyMatVec(matrix, getLookAt())); } if (hasField(REPO_NODE_LABEL_POSITION)) { builder.append(REPO_NODE_LABEL_POSITION, multiplyMatVec(matrix, getPosition())); } if (hasField(REPO_NODE_LABEL_UP)) { builder.append(REPO_NODE_LABEL_UP, multiplyMatVec(matrix, getUp())); } return CameraNode(builder.appendElementsUnique(*this)); }
RepoNode RepoNode::cloneAndAddParent( const std::vector<repoUUID> &parentIDs) const { RepoBSONBuilder builder; RepoBSONBuilder arrayBuilder; std::vector<repoUUID> currentParents = getParentIDs(); currentParents.insert(currentParents.end(), parentIDs.begin(), parentIDs.end()); std::sort(currentParents.begin(), currentParents.end()); auto last = std::unique(currentParents.begin(), currentParents.end()); if (last != currentParents.end()) currentParents.erase(last, currentParents.end()); builder.appendArray(REPO_NODE_LABEL_PARENTS, currentParents); builder.appendElementsUnique(*this); return RepoNode(builder.obj(), bigFiles); }
RepoNode MeshNode::cloneAndApplyTransformation( const std::vector<float> &matrix) const { std::vector<repo_vector_t> vertices = getVertices(); std::vector<repo_vector_t> normals = getNormals(); auto newBigFiles = bigFiles; RepoBSONBuilder builder; std::vector<repo_vector_t> resultVertice; std::vector<repo_vector_t> newBbox; if (vertices.size()) { resultVertice.reserve(vertices.size()); for (const repo_vector_t &v : vertices) { resultVertice.push_back(multiplyMatVec(matrix, v)); if (newBbox.size()) { if (resultVertice.back().x < newBbox[0].x) newBbox[0].x = resultVertice.back().x; if (resultVertice.back().y < newBbox[0].y) newBbox[0].y = resultVertice.back().y; if (resultVertice.back().z < newBbox[0].z) newBbox[0].z = resultVertice.back().z; if (resultVertice.back().x > newBbox[1].x) newBbox[1].x = resultVertice.back().x; if (resultVertice.back().y > newBbox[1].y) newBbox[1].y = resultVertice.back().y; if (resultVertice.back().z > newBbox[1].z) newBbox[1].z = resultVertice.back().z; } else { newBbox.push_back(resultVertice.back()); newBbox.push_back(resultVertice.back()); } } if (newBigFiles.find(REPO_NODE_MESH_LABEL_VERTICES) != newBigFiles.end()) { const uint64_t verticesByteCount = resultVertice.size() * sizeof(repo_vector_t); newBigFiles[REPO_NODE_MESH_LABEL_VERTICES].second.resize(verticesByteCount); memcpy(newBigFiles[REPO_NODE_MESH_LABEL_VERTICES].second.data(), resultVertice.data(), verticesByteCount); } else builder.appendBinary(REPO_NODE_MESH_LABEL_VERTICES, resultVertice.data(), resultVertice.size() * sizeof(repo_vector_t)); if (normals.size()) { auto matInverse = invertMat(matrix); auto worldMat = transposeMat(matInverse); std::vector<repo_vector_t> resultNormals; resultNormals.reserve(normals.size()); for (const repo_vector_t &v : normals) { auto transformedNormal = multiplyMatVecFake3x3(worldMat, v); normalize(transformedNormal); resultNormals.push_back(transformedNormal); } if (newBigFiles.find(REPO_NODE_MESH_LABEL_NORMALS) != newBigFiles.end()) { const uint64_t byteCount = resultNormals.size() * sizeof(repo_vector_t); newBigFiles[REPO_NODE_MESH_LABEL_NORMALS].second.resize(byteCount); memcpy(newBigFiles[REPO_NODE_MESH_LABEL_NORMALS].second.data(), resultNormals.data(), byteCount); } else builder.appendBinary(REPO_NODE_MESH_LABEL_NORMALS, resultNormals.data(), resultNormals.size() * sizeof(repo_vector_t)); } RepoBSONBuilder arrayBuilder, outlineBuilder; for (size_t i = 0; i < newBbox.size(); ++i) { std::vector<float> boundVec = { newBbox[i].x, newBbox[i].y, newBbox[i].z }; arrayBuilder.appendArray(std::to_string(i), boundVec); } if (newBbox[0].x > newBbox[1].x || newBbox[0].z > newBbox[1].z || newBbox[0].y > newBbox[1].y) { repoError << "New bounding box is incorrect!!!"; } builder.appendArray(REPO_NODE_MESH_LABEL_BOUNDING_BOX, arrayBuilder.obj()); std::vector<float> outline0 = { newBbox[0].x, newBbox[0].y }; std::vector<float> outline1 = { newBbox[1].x, newBbox[0].y }; std::vector<float> outline2 = { newBbox[1].x, newBbox[1].y }; std::vector<float> outline3 = { newBbox[0].x, newBbox[1].y }; outlineBuilder.appendArray("0", outline0); outlineBuilder.appendArray("1", outline1); outlineBuilder.appendArray("2", outline2); outlineBuilder.appendArray("3", outline3); builder.appendArray(REPO_NODE_MESH_LABEL_OUTLINE, outlineBuilder.obj()); return MeshNode(builder.appendElementsUnique(*this), newBigFiles); } else { repoError << "Unable to apply transformation: Cannot find vertices within a mesh!"; return RepoNode(this->copy(), bigFiles); } }