MetadataNode RepoBSONFactory::makeMetaDataNode( RepoBSON &metadata, const std::string &mimeType, const std::string &name, const std::vector<repoUUID> &parents, 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_METADATA, apiLevel, generateUUID(), name, parents); builder.appendElements(defaults); //-------------------------------------------------------------------------- // Media type if (!mimeType.empty()) builder << REPO_LABEL_MEDIA_TYPE << mimeType; //-------------------------------------------------------------------------- // Add metadata subobject if (!metadata.isEmpty()) builder << REPO_NODE_LABEL_METADATA << metadata; return MetadataNode(builder.obj()); }
MeshNode MeshNode::cloneAndUpdateMeshMapping( const std::vector<repo_mesh_mapping_t> &vec, const bool &overwrite) { RepoBSONBuilder builder, mapbuilder; uint32_t index = 0; std::vector<repo_mesh_mapping_t> mappings; RepoBSON mapArray = getObjectField(REPO_NODE_MESH_LABEL_MERGE_MAP); if (!overwrite && !mapArray.isEmpty()) { //if map array isn't empty, find the next index it needs to slot in std::set<std::string> fields; mapArray.getFieldNames(fields); index = fields.size(); } for (uint32_t i = 0; i < vec.size(); ++i) { mapbuilder << std::to_string(index + i) << meshMappingAsBSON(vec[i]); } //append the rest of the array onto this new map bson if (!overwrite) mapbuilder.appendElementsUnique(mapArray); builder.appendArray(REPO_NODE_MESH_LABEL_MERGE_MAP, mapbuilder.obj()); //append the rest of the mesh onto this new bson builder.appendElementsUnique(*this); return MeshNode(builder.obj(), bigFiles); }
std::vector<repoUUID> RepoBSON::getUUIDFieldArray(const std::string &label) const{ std::vector<repoUUID> results; if (hasField(label)) { RepoBSON array = getObjectField(label); if (!array.isEmpty()) { std::set<std::string> fields; array.getFieldNames(fields); std::set<std::string>::iterator it; for (it = fields.begin(); it != fields.end(); ++it) results.push_back(array.getUUIDField(*it)); } else { repoError << "getUUIDFieldArray: field " << label << " is an empty bson or wrong type!"; } } return results; }
bool RepoScene::commitProjectSettings( repo::core::handler::AbstractDatabaseHandler *handler, std::string &errMsg, const std::string &userName) { RepoProjectSettings projectSettings = RepoBSONFactory::makeRepoProjectSettings(projectName, userName); bool success = handler->insertDocument( databaseName, REPO_COLLECTION_SETTINGS, projectSettings, errMsg); if (!success) { //check that the error occurred because of duplicated index (i.e. there's already an entry for projects) RepoBSON criteria = BSON(REPO_LABEL_ID << projectName); RepoBSON doc = handler->findOneByCriteria(databaseName, REPO_COLLECTION_SETTINGS, criteria); //If it already exist, that's fine. success = !doc.isEmpty(); if (success) { repoTrace << "This project already has a project settings entry, skipping project settings commit..."; errMsg.clear(); } } return success; }
RepoProjectSettings RepoBSONFactory::makeRepoProjectSettings( const std::string &uniqueProjectName, const std::string &owner, const std::string &type, const std::string &description, const double pinSize, const double avatarHeight, const double visibilityLimit, const double speed, const double zNear, const double zFar) { RepoBSONBuilder builder; //-------------------------------------------------------------------------- // Project name if (!uniqueProjectName.empty()) builder << REPO_LABEL_ID << uniqueProjectName; //-------------------------------------------------------------------------- // Owner if (!owner.empty()) builder << REPO_LABEL_OWNER << owner; //-------------------------------------------------------------------------- // Description if (!description.empty()) builder << REPO_LABEL_DESCRIPTION << description; //-------------------------------------------------------------------------- // Type if (!type.empty()) builder << REPO_LABEL_TYPE << type; //-------------------------------------------------------------------------- // Properties (embedded sub-bson) RepoBSONBuilder propertiesBuilder; if (pinSize != REPO_DEFAULT_PROJECT_PIN_SIZE) propertiesBuilder << REPO_LABEL_PIN_SIZE << pinSize; if (avatarHeight != REPO_DEFAULT_PROJECT_AVATAR_HEIGHT) propertiesBuilder << REPO_LABEL_AVATAR_HEIGHT << avatarHeight; if (visibilityLimit != REPO_DEFAULT_PROJECT_VISIBILITY_LIMIT) propertiesBuilder << REPO_LABEL_VISIBILITY_LIMIT << visibilityLimit; if (speed != REPO_DEFAULT_PROJECT_SPEED) propertiesBuilder << REPO_LABEL_SPEED << speed; if (zNear != REPO_DEFAULT_PROJECT_ZNEAR) propertiesBuilder << REPO_LABEL_ZNEAR << zNear; if (zFar != REPO_DEFAULT_PROJECT_ZFAR) propertiesBuilder << REPO_LABEL_ZFAR << zFar; RepoBSON propertiesBSON = propertiesBuilder.obj(); if (propertiesBSON.isValid() && !propertiesBSON.isEmpty()) builder << REPO_LABEL_PROPERTIES << propertiesBSON; //-------------------------------------------------------------------------- // Add to the parent object return RepoProjectSettings(builder.obj()); }
std::vector<repo_vector_t> MeshNode::getBoundingBox(RepoBSON &bbArr) { std::vector<repo_vector_t> bbox; if (!bbArr.isEmpty() && bbArr.couldBeArray()) { size_t nVec = bbArr.nFields(); bbox.reserve(nVec); for (uint32_t i = 0; i < nVec; ++i) { auto bbVectorBson = bbArr.getObjectField(std::to_string(i)); if (!bbVectorBson.isEmpty() && bbVectorBson.couldBeArray()) { int32_t nFields = bbVectorBson.nFields(); if (nFields >= 3) { repo_vector_t vector; vector.x = bbVectorBson.getField("0").Double(); vector.y = bbVectorBson.getField("1").Double(); vector.z = bbVectorBson.getField("2").Double(); bbox.push_back(vector); } else { repoError << "Insufficient amount of elements within bounding box! #fields: " << nFields; } } else { repoError << "Failed to get a vector for bounding box!"; } } } else { repoError << "Failed to fetch bounding box from Mesh Node!"; } return bbox; }
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; }
std::vector<repo_mesh_mapping_t> MeshNode::getMeshMapping() const { std::vector<repo_mesh_mapping_t> mappings; RepoBSON mapArray = getObjectField(REPO_NODE_MESH_LABEL_MERGE_MAP); if (!mapArray.isEmpty()) { std::set<std::string> fields; mapArray.getFieldNames(fields); mappings.resize(fields.size()); for (const auto &name : fields) { repo_mesh_mapping_t mapping; RepoBSON mappingObj = mapArray.getObjectField(name); mapping.mesh_id = mappingObj.getUUIDField(REPO_NODE_MESH_LABEL_MAP_ID); mapping.material_id = mappingObj.getUUIDField(REPO_NODE_MESH_LABEL_MATERIAL_ID); mapping.vertFrom = mappingObj.getField(REPO_NODE_MESH_LABEL_VERTEX_FROM).Int(); mapping.vertTo = mappingObj.getField(REPO_NODE_MESH_LABEL_VERTEX_TO).Int(); mapping.triFrom = mappingObj.getField(REPO_NODE_MESH_LABEL_TRIANGLE_FROM).Int(); mapping.triTo = mappingObj.getField(REPO_NODE_MESH_LABEL_TRIANGLE_TO).Int(); RepoBSON boundingBox = mappingObj.getObjectField(REPO_NODE_MESH_LABEL_BOUNDING_BOX); std::vector<repo_vector_t> bboxVec = getBoundingBox(boundingBox); mapping.min.x = bboxVec[0].x; mapping.min.y = bboxVec[0].y; mapping.min.z = bboxVec[0].z; mapping.max.x = bboxVec[1].x; mapping.max.y = bboxVec[1].y; mapping.max.z = bboxVec[1].z; mappings[std::stoi(name)] = mapping; } } return mappings; }
std::vector<float> RepoBSON::getFloatArray(const std::string &label) const { std::vector<float> results; if (hasField(label)) { RepoBSON array = getObjectField(label); if (!array.isEmpty()) { std::set<std::string> fields; array.getFieldNames(fields); // Pre allocate memory to speed up copying results.reserve(fields.size()); for (auto field : fields) results.push_back(array.getField(field).numberDouble()); } else { repoError << "getFloatArray: field " << label << " is an empty bson or wrong type!"; } } return results; }