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); }
CameraNode RepoBSONFactory::makeCameraNode( const float &aspectRatio, const float &farClippingPlane, const float &nearClippingPlane, const float &fieldOfView, const repo_vector_t &lookAt, const repo_vector_t &position, const repo_vector_t &up, const std::string &name, const int &apiLevel) { RepoBSONBuilder builder; //-------------------------------------------------------------------------- // Compulsory fields such as _id, type, api as well as path // and optional name auto defaults = appendDefaults(REPO_NODE_TYPE_CAMERA, apiLevel, generateUUID(), name); builder.appendElements(defaults); //-------------------------------------------------------------------------- // Aspect ratio builder << REPO_NODE_LABEL_ASPECT_RATIO << aspectRatio; //-------------------------------------------------------------------------- // Far clipping plane builder << REPO_NODE_LABEL_FAR << farClippingPlane; //-------------------------------------------------------------------------- // Near clipping plane builder << REPO_NODE_LABEL_NEAR << nearClippingPlane; //-------------------------------------------------------------------------- // Field of view builder << REPO_NODE_LABEL_FOV << fieldOfView; //-------------------------------------------------------------------------- // Look at vector builder.append(REPO_NODE_LABEL_LOOK_AT, lookAt); //-------------------------------------------------------------------------- // Position vector builder.append(REPO_NODE_LABEL_POSITION, position); //-------------------------------------------------------------------------- // Up vector builder.append(REPO_NODE_LABEL_UP, up); return CameraNode(builder.obj()); }
RepoBSON RepoBSONFactory::appendDefaults( const std::string &type, const unsigned int api, const repoUUID &sharedId, const std::string &name, const std::vector<repoUUID> &parents, const repoUUID &uniqueID) { RepoBSONBuilder builder; uint64_t bytesize = 0; //-------------------------------------------------------------------------- // ID field (UUID) builder.append(REPO_NODE_LABEL_ID, uniqueID); //-------------------------------------------------------------------------- // Shared ID (UUID) builder.append(REPO_NODE_LABEL_SHARED_ID, sharedId); bytesize += 2 * sizeof(repoUUID); //-------------------------------------------------------------------------- // Type if (!type.empty()) { builder << REPO_NODE_LABEL_TYPE << type; } //-------------------------------------------------------------------------- // API level builder << REPO_NODE_LABEL_API << api; //-------------------------------------------------------------------------- // Parents if (parents.size() > 0) { builder.appendArray(REPO_NODE_LABEL_PARENTS, parents); } //-------------------------------------------------------------------------- // Name if (!name.empty()) { builder << REPO_NODE_LABEL_NAME << name; } return builder.obj(); }
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); }
bool RepoScene::loadStash( repo::core::handler::AbstractDatabaseHandler *handler, std::string &errMsg){ bool success = true; if (!handler) { errMsg += "Trying to load stash graph without a database handler!"; return false; } if (!revNode){ if (!loadRevision(handler, errMsg)) return false; } //Get the relevant nodes from the scene graph using the unique IDs stored in this revision node RepoBSONBuilder builder; builder.append(REPO_NODE_STASH_REF, revNode->getUniqueID()); std::vector<RepoBSON> nodes = handler->findAllByCriteria(databaseName, projectName + "." + stashExt, builder.obj()); if (success = nodes.size()) { repoInfo << "# of nodes in this stash scene = " << nodes.size(); success = populate(GraphType::OPTIMIZED, handler, nodes, errMsg); } else { errMsg += "stash is empty"; } return success; }
RepoBSON MeshNode::meshMappingAsBSON(const repo_mesh_mapping_t &mapping) { RepoBSONBuilder builder; builder.append(REPO_NODE_MESH_LABEL_MAP_ID, mapping.mesh_id); builder.append(REPO_NODE_MESH_LABEL_MATERIAL_ID, mapping.material_id); builder << REPO_NODE_MESH_LABEL_VERTEX_FROM << mapping.vertFrom; builder << REPO_NODE_MESH_LABEL_VERTEX_TO << mapping.vertTo; builder << REPO_NODE_MESH_LABEL_TRIANGLE_FROM << mapping.triFrom; builder << REPO_NODE_MESH_LABEL_TRIANGLE_TO << mapping.triTo; RepoBSONBuilder bbBuilder; bbBuilder.append("0", mapping.min); bbBuilder.append("1", mapping.max); builder.appendArray(REPO_NODE_MESH_LABEL_BOUNDING_BOX, bbBuilder.obj()); return builder.obj(); }
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)); }
bool RepoScene::commitStash( repo::core::handler::AbstractDatabaseHandler *handler, std::string &errMsg) { /* * Don't bother if: * 1. root node is null (not instantiated) * 2. revnode is null (unoptimised scene graph needs to be commited first */ repoUUID rev; if (!handler) { errMsg += "Cannot commit stash graph - nullptr to database handler."; return false; } if (!revNode) { errMsg += "Revision node not found, make sure the default scene graph is commited"; return false; } else { rev = revNode->getUniqueID(); } if (stashGraph.rootNode) { updateRevisionStatus(handler, repo::core::model::RevisionNode::UploadStatus::GEN_REPO_STASH); //Add rev id onto the stash nodes before committing. std::vector<repoUUID> nodes; RepoBSONBuilder builder; builder.append(REPO_NODE_STASH_REF, rev); RepoBSON revID = builder.obj(); // this should be RepoBSON? for (auto &pair : stashGraph.nodesByUniqueID) { nodes.push_back(pair.first); *pair.second = pair.second->cloneAndAddFields(&revID, false); } auto success = commitNodes(handler, nodes, GraphType::OPTIMIZED, errMsg); if (success) updateRevisionStatus(handler, repo::core::model::RevisionNode::UploadStatus::COMPLETE); return success; } else { //Not neccessarily an error. Make it visible for debugging purposes repoDebug << "Stash graph not commited. Root node is nullptr!"; return true; } }
RepoUser RepoBSONFactory::makeRepoUser( const std::string &userName, const std::string &password, const std::string &firstName, const std::string &lastName, const std::string &email, const std::list<std::pair<std::string, std::string>> &roles, const std::list<std::pair<std::string, std::string>> &apiKeys, const std::vector<char> &avatar) { RepoBSONBuilder builder; RepoBSONBuilder customDataBuilder; builder.append(REPO_LABEL_ID, generateUUID()); if (!userName.empty()) builder << REPO_USER_LABEL_USER << userName; if (!password.empty()) { RepoBSONBuilder credentialsBuilder; credentialsBuilder << REPO_USER_LABEL_CLEARTEXT << password; builder << REPO_USER_LABEL_CREDENTIALS << credentialsBuilder.obj(); } if (!firstName.empty()) customDataBuilder << REPO_USER_LABEL_FIRST_NAME << firstName; if (!lastName.empty()) customDataBuilder << REPO_USER_LABEL_LAST_NAME << lastName; if (!email.empty()) customDataBuilder << REPO_USER_LABEL_EMAIL << email; if (!apiKeys.empty()) customDataBuilder.appendArrayPair(REPO_USER_LABEL_API_KEYS, apiKeys, REPO_USER_LABEL_LABEL, REPO_USER_LABEL_KEY); if (avatar.size()) { RepoBSONBuilder avatarBuilder; avatarBuilder.appendBinary(REPO_LABEL_DATA, &avatar.at(0), sizeof(avatar.at(0))*avatar.size()); customDataBuilder << REPO_LABEL_AVATAR << avatarBuilder.obj(); } builder << REPO_USER_LABEL_CUSTOM_DATA << customDataBuilder.obj(); if (roles.size()) builder.appendArrayPair(REPO_USER_LABEL_ROLES, roles, REPO_USER_LABEL_DB, REPO_USER_LABEL_ROLE); return RepoUser(builder.obj()); }
TransformationNode RepoBSONFactory::makeTransformationNode( const repo::lib::RepoMatrix &transMatrix, const std::string &name, const std::vector<repo::lib::RepoUUID> &parents, const int &apiLevel) { RepoBSONBuilder builder; auto defaults = appendDefaults(REPO_NODE_TYPE_TRANSFORMATION, apiLevel, repo::lib::RepoUUID::createUUID(), name, parents); builder.appendElements(defaults); builder.append(REPO_NODE_LABEL_MATRIX, transMatrix); return TransformationNode(builder.obj()); }
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); }
bool RepoScene::loadRevision( repo::core::handler::AbstractDatabaseHandler *handler, std::string &errMsg){ bool success = true; if (!handler) { errMsg = "Cannot load revision with an empty database handler"; return false; } RepoBSON bson; repoTrace << "loading revision : " << databaseName << "." << projectName << " head Revision: " << headRevision; if (headRevision){ RepoBSONBuilder critBuilder; critBuilder.append(REPO_NODE_LABEL_SHARED_ID, branch); critBuilder << REPO_NODE_REVISION_LABEL_INCOMPLETE << BSON("$exists" << false); bson = handler->findOneByCriteria(databaseName, projectName + "." + revExt, critBuilder.obj(), REPO_NODE_REVISION_LABEL_TIMESTAMP); repoTrace << "Fetching head of revision from branch " << UUIDtoString(branch); } else{ bson = handler->findOneByUniqueID(databaseName, projectName + "." + revExt, revision); repoTrace << "Fetching revision using unique ID: " << UUIDtoString(revision); } if (bson.isEmpty()){ errMsg = "Failed: cannot find revision document from " + databaseName + "." + projectName + "." + revExt; success = false; } else{ revNode = new RevisionNode(bson); worldOffset = revNode->getCoordOffset(); } return success; }
ReferenceNode RepoBSONFactory::makeReferenceNode( const std::string &database, const std::string &project, const repoUUID &revisionID, const bool &isUniqueID, const std::string &name, const int &apiLevel) { RepoBSONBuilder builder; std::string nodeName = name.empty() ? database + "." + project : name; auto defaults = appendDefaults(REPO_NODE_TYPE_REFERENCE, apiLevel, generateUUID(), nodeName); builder.appendElements(defaults); //-------------------------------------------------------------------------- // Project owner (company or individual) if (!database.empty()) builder << REPO_NODE_REFERENCE_LABEL_OWNER << database; //-------------------------------------------------------------------------- // Project name if (!project.empty()) builder << REPO_NODE_REFERENCE_LABEL_PROJECT << project; //-------------------------------------------------------------------------- // Revision ID (specific revision if UID, branch if SID) builder.append( REPO_NODE_REFERENCE_LABEL_REVISION_ID, revisionID); //-------------------------------------------------------------------------- // Unique set if the revisionID is UID, not set if SID (branch) if (isUniqueID) builder << REPO_NODE_REFERENCE_LABEL_UNIQUE << isUniqueID; return ReferenceNode(builder.obj()); }