From d4e4ba743772e8f88a402f8c025a27678f057c42 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Tue, 14 May 2024 07:46:31 -0400 Subject: [PATCH 01/14] --define hidden fields for file paths These fields will hold the fully qualified file paths that we wish to consume internally but do not wish to write to disk. --- .../attributes/AbstractObjectAttributes.h | 36 ++++++++++ .../attributes/ArticulatedObjectAttributes.h | 37 ++++++++++ .../metadata/attributes/SemanticAttributes.h | 57 ++++++++++++--- src/esp/metadata/attributes/StageAttributes.h | 72 +++++++++++++++++++ .../metadata/managers/AttributesManagerBase.h | 2 + .../managers/StageAttributesManager.cpp | 11 ++- 6 files changed, 201 insertions(+), 14 deletions(-) diff --git a/src/esp/metadata/attributes/AbstractObjectAttributes.h b/src/esp/metadata/attributes/AbstractObjectAttributes.h index b1d31a1383..30447d58fb 100644 --- a/src/esp/metadata/attributes/AbstractObjectAttributes.h +++ b/src/esp/metadata/attributes/AbstractObjectAttributes.h @@ -126,6 +126,25 @@ class AbstractObjectAttributes : public AbstractAttributes { return get("render_asset"); } + /** + * @brief Sets the fully-qualified filepath for the render asset to be used to + * render the construct this attributes describes. This is only used + * internally and should not be saved to disk. + */ + void setRenderAssetFullPath(const std::string& renderAssetHandle) { + setHidden("__renderAssetFullPath", renderAssetHandle); + setIsDirty(); + } + + /** + * @brief Gets the fully-qualified filepath for the render asset to be used to + * render the construct this attributes describes. This is only used + * internally and should not be saved to disk. + */ + std::string getRenderAssetFullPath() const { + return get("__renderAssetFullPath"); + } + /** * @brief Sets the render asset type, as specified by @ref AssetType. * This specification was generally intended for specifying certain criteria @@ -265,7 +284,24 @@ class AbstractObjectAttributes : public AbstractAttributes { std::string getCollisionAssetHandle() const { return get("collision_asset"); } + /** + * @brief Sets the fully-qualified filepath for the collision asset to be used + * for mesh collision detection for the construct this attributes describes. + * This is only used internally and should not be saved to disk. + */ + void setCollisionAssetFullPath(const std::string& collisionAssetHandle) { + setHidden("__collisionAssetFullPath", collisionAssetHandle); + setIsDirty(); + } + /** + * @brief Gets the fully-qualified filepath for the collision asset to be used + * for mesh collision detection for the construct this attributes describes. + * This is only used internally and should not be saved to disk. + */ + std::string getCollisionAssetFullPath() const { + return get("__collisionAssetFullPath"); + } /** * @brief Sets the collision asset type, as specified by @ref AssetType. * This specification was generally intended for specifying certain criteria diff --git a/src/esp/metadata/attributes/ArticulatedObjectAttributes.h b/src/esp/metadata/attributes/ArticulatedObjectAttributes.h index 8052f4a6d2..2a7f36a8ff 100644 --- a/src/esp/metadata/attributes/ArticulatedObjectAttributes.h +++ b/src/esp/metadata/attributes/ArticulatedObjectAttributes.h @@ -29,6 +29,25 @@ class ArticulatedObjectAttributes : public AbstractAttributes { * @brief Gets the string name for the Articulated Object URDF relative path */ std::string getURDFPath() const { return get("urdf_filepath"); } + + /** + * @brief Sets the fully-qualified filepath for for the Articulated Object + * URDF to be used to create the articulated object this attributes describes. + * This is only used internally and should not be saved to disk. + */ + void setURDFFullPath(const std::string& urdfFilepath) { + setHidden("__urdfFullPath", urdfFilepath); + } + + /** + * @brief Gets the fully-qualified filepath for for the Articulated Object + * URDF to be used to create the articulated object this attributes describes. + * This is only used internally and should not be saved to disk. + */ + std::string getURDFFullPath() const { + return get("__urdfFullPath"); + } + /** * @brief Sets the string name for the render asset relative path */ @@ -42,6 +61,24 @@ class ArticulatedObjectAttributes : public AbstractAttributes { return get("render_asset"); } + /** + * @brief Sets the fully-qualified filepath for the render asset to be used to + * render the construct this attributes describes. This is only used + * internally and should not be saved to disk. + */ + void setRenderAssetFullPath(const std::string& renderAssetHandle) { + setHidden("__renderAssetFullPath", renderAssetHandle); + } + + /** + * @brief Gets the fully-qualified filepath for the render asset to be used to + * render the construct this attributes describes. This is only used + * internally and should not be saved to disk. + */ + std::string getRenderAssetFullPath() const { + return get("__renderAssetFullPath"); + } + /** * @brief Set uniform scaling of the articulated object. */ diff --git a/src/esp/metadata/attributes/SemanticAttributes.h b/src/esp/metadata/attributes/SemanticAttributes.h index efb65a478d..6775dcc198 100644 --- a/src/esp/metadata/attributes/SemanticAttributes.h +++ b/src/esp/metadata/attributes/SemanticAttributes.h @@ -179,37 +179,78 @@ class SemanticAttributes : public AbstractAttributes { } /** - * @brief Set the filename to the text file that describes the hierharchy of - * semantic information embedded in the Semantic Asset mesh. May be - * overridden by value specified in Scene Instance Attributes. + * @brief Set the relative filename to the text file that describes the + * hierharchy of semantic information embedded in the Semantic Asset mesh. May + * be overridden by value specified in Scene Instance Attributes. */ void setSemanticDescriptorFilename( const std::string& semantic_descriptor_filename) { set("semantic_descriptor_filename", semantic_descriptor_filename); } /** - * @brief Get the filename to the text file that describes the hierharchy of - * semantic information embedded in the Semantic Asset mesh. May be - * overridden by value specified in Scene Instance Attributes. + * @brief Get the relative filename to the text file that describes the + * hierharchy of semantic information embedded in the Semantic Asset mesh. May + * be overridden by value specified in Scene Instance Attributes. */ std::string getSemanticDescriptorFilename() const { return get("semantic_descriptor_filename"); } /** - * @brief Set the Filename to the semantic texture mesh, if one exists. + * @brief Sets the fully-qualified filename to the text file that describes + * the hierharchy of semantic information embedded in the Semantic Asset mesh. + * May be overridden by value specified in Scene Instance Attributes. This is + * only used internally and should not be saved to disk. + */ + void setSemanticDescriptorFullPath( + const std::string& semanticDescriptorHandle) { + setHidden("__semanticDescriptorFullPath", semanticDescriptorHandle); + } + + /** + * @brief Gets the fully-qualified filename to the text file that describes + * the hierharchy of semantic information embedded in the Semantic Asset mesh. + * May be overridden by value specified in Scene Instance Attributes. This is + * only used internally and should not be saved to disk. + */ + std::string getSemanticDescriptorFullPath() const { + return get("__semanticDescriptorFullPath"); + } + + /** + * @brief Set the retlative Filename to the semantic texture mesh, if one + * exists. */ void setSemanticAssetHandle(const std::string& semanticAssetHandle) { set("semantic_asset", semanticAssetHandle); } /** - * @brief Get the Filename to the semantic texture mesh, if one exists. + * @brief Get the relative Filename to the semantic texture mesh, if one + * exists. */ std::string getSemanticAssetHandle() const { return get("semantic_asset"); } + /** + * @brief Sets the fully-qualified filepath for the semantic asset to be used + * to render the semantics for the stage this attributes describes. This is + * only used internally and should not be saved to disk. + */ + void setSemanticAssetFullPath(const std::string& semanticAssetHandle) { + setHidden("__semanticAssetFullPath", semanticAssetHandle); + } + + /** + * @brief Gets the fully-qualified filepath for the semantic asset to be used + * to render the semantics for the stage this attributes describes. This is + * only used internally and should not be saved to disk. + */ + std::string getSemanticAssetFullPath() const { + return get("__semanticAssetFullPath"); + } + /** * @brief Sets the semantic asset type, as specified by @ref AssetType. * This specification was generally intended for specifying certain criteria diff --git a/src/esp/metadata/attributes/StageAttributes.h b/src/esp/metadata/attributes/StageAttributes.h index 9edf3c1951..7c7fbe9a24 100644 --- a/src/esp/metadata/attributes/StageAttributes.h +++ b/src/esp/metadata/attributes/StageAttributes.h @@ -92,14 +92,67 @@ class StageAttributes : public AbstractObjectAttributes { std::string getSemanticDescriptorFilename() const { return get("semantic_descriptor_filename"); } + + /** + * @brief Sets the fully-qualified filepath for the semantic asset to be used + * to semantic the construct this attributes describes. This is only used + * internally and should not be saved to disk. + */ + void setSemanticDescriptorFullPath( + const std::string& semanticDescriptorHandle) { + setHidden("__semanticDescriptorFullPath", semanticDescriptorHandle); + setIsDirty(); + } + + /** + * @brief Gets the fully-qualified filepath for the semantic asset to be used + * to semantic the construct this attributes describes. This is only used + * internally and should not be saved to disk. + */ + std::string getSemanticDescriptorFullPath() const { + return get("__semanticDescriptorFullPath"); + } + + /** + * @brief Sets the relative path/filename for the semantic asset to be used to + * render the semantics for the stage this attributes describes. This is + * relative to the on-disk location of the file responsible for this + * configuration. + */ void setSemanticAssetHandle(const std::string& semanticAssetHandle) { set("semantic_asset", semanticAssetHandle); setIsDirty(); } + + /** + * @brief Gets the relative path/filename for the semantic asset to be used to + * render the semantics for the stage this attributes describes. This is + * relative to the on-disk location of the file responsible for this + * configuration. + */ std::string getSemanticAssetHandle() const { return get("semantic_asset"); } + /** + * @brief Sets the fully-qualified filepath for the semantic asset to be used + * to render the semantics for the stage this attributes describes. This is + * only used internally and should not be saved to disk. + */ + void setSemanticAssetFullPath(const std::string& semanticAssetHandle) { + setHidden("__semanticAssetFullPath", semanticAssetHandle); + setIsDirty(); + } + + /** + * @brief Gets the fully-qualified filepath for the semantic asset to be used + * to render the semantics for the stage this attributes describes. This is + * only used internally and should not be saved to disk. + */ + std::string getSemanticAssetFullPath() const { + return get("__semanticAssetFullPath"); + } + /** * @brief Sets the semantic asset type, as specified by @ref AssetType. * This specification was generally intended for specifying certain criteria @@ -251,6 +304,25 @@ class StageAttributes : public AbstractObjectAttributes { return get("nav_asset"); } + /** + * @brief Sets the fully-qualified filepath for the navmesh asset to be used + * with the stage this attributes describes. This is only used internally and + * should not be saved to disk. + */ + void setNavmeshAssetFullPath(const std::string& navmeshAssetHandle) { + setHidden("__navmeshAssetFullPath", navmeshAssetHandle); + setIsDirty(); + } + + /** + * @brief Gets the fully-qualified filepath for the navmesh asset to be used + * with the stage this attributes describes. This is only used internally and + * should not be saved to disk. + */ + std::string getNavmeshAssetFullPath() const { + return get("__navmeshAssetFullPath"); + } + /** * @brief Set lighting setup for stage. Default value comes from * @ref esp::sim::SimulatorConfiguration, is overridden by any value set in diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index fa1744efed..53c81992e4 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -266,6 +266,8 @@ class AttributesManager : public ManagedFileBasedContainer { * @param jsonTag The field to look for. If present expected to hold a string * @param mapName String map name, to be displayed if the value found in json * is not found in @p mapToUse + * @param saveUnspecified Whether to save the 'unspecified' string in value + * setter if no value is specified in json. * @param mapToUse String-keyed map of enum values supported for the field * that corresponds to @p jsonTag. See attributes::AttributesEnumMaps.h/cpp. * @param valueSetter The config function to use to set the value diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index 785551e291..e257a1986b 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -285,14 +285,14 @@ StageAttributes::ptr StageAttributesManager::initNewObjectInternal( // set default origin and orientation values based on file name // from AssetInfo::fromPath // set defaults for passed render asset handles - StageAttributesManager::setDefaultAssetNameBasedAttributes( + this->setDefaultAssetNameBasedAttributes( newAttributes, createNewAttributes, newAttributes->getRenderAssetHandle(), [newAttributes](auto&& PH1) { newAttributes->initRenderAssetTypeEnum( std::forward(PH1)); }); // set defaults for passed collision asset handles - StageAttributesManager::setDefaultAssetNameBasedAttributes( + this->setDefaultAssetNameBasedAttributes( newAttributes, false, newAttributes->getCollisionAssetHandle(), [newAttributes](auto&& PH1) { newAttributes->initCollisionAssetTypeEnum( @@ -300,7 +300,7 @@ StageAttributes::ptr StageAttributesManager::initNewObjectInternal( }); // set defaults for passed semantic asset handles - StageAttributesManager::setDefaultAssetNameBasedAttributes( + this->setDefaultAssetNameBasedAttributes( newAttributes, false, newAttributes->getSemanticAssetHandle(), [newAttributes](auto&& PH1) { newAttributes->initSemanticAssetTypeEnum( @@ -404,9 +404,6 @@ void StageAttributesManager::setValsFromJSONDoc( // populate specified semantic file name if specified in json - defaults // are overridden only if specified in json. - std::string navmeshFName = ""; - std::string semanticSceneDescriptor = ""; - // populate semantic mesh type if present std::string semanticFName = stageAttributes->getSemanticAssetHandle(); semanticFName = this->setJSONAssetHandleAndType( @@ -422,6 +419,7 @@ void StageAttributesManager::setValsFromJSONDoc( // instance stageAttributes->initSemanticAssetTypeEnum(AssetType::InstanceMesh); + std::string navmeshFName = ""; if (io::readMember(jsonConfig, "nav_asset", navmeshFName)) { // if "nav mesh" is specified in stage json set value (override default). // navmesh filename might already be fully qualified; if not, might just be @@ -433,6 +431,7 @@ void StageAttributesManager::setValsFromJSONDoc( stageAttributes->setNavmeshAssetHandle(navmeshFName); } + std::string semanticSceneDescriptor = ""; if (io::readMember(jsonConfig, "semantic_descriptor_filename", semanticSceneDescriptor)) { // if "semantic_descriptor_filename" is specified in stage json, set value From 93f07caff61e708324ffee9769910be842b3e82e Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Wed, 15 May 2024 17:07:03 -0400 Subject: [PATCH 02/14] --initial pass of file handle normalization before registration Remove the path and have only relative filepath in primary handle attribute; put fully qualified version in hidden handle attribute. Still fails in some edge cases --- src/esp/assets/ResourceManager.cpp | 38 +-- src/esp/metadata/MetadataMediator.cpp | 6 +- .../attributes/AbstractObjectAttributes.cpp | 4 +- .../ArticulatedObjectAttributes.cpp | 5 + .../attributes/SceneDatasetAttributes.cpp | 14 +- .../attributes/SemanticAttributes.cpp | 3 + .../metadata/attributes/StageAttributes.cpp | 4 + .../metadata/managers/AOAttributesManager.cpp | 76 +++-- .../metadata/managers/AttributesManagerBase.h | 95 +++++-- .../managers/ObjectAttributesManager.cpp | 59 +++- .../managers/SemanticAttributesManager.cpp | 41 +++ .../managers/SemanticAttributesManager.h | 18 +- .../managers/StageAttributesManager.cpp | 261 ++++++++++++------ .../physics/bullet/BulletPhysicsManager.cpp | 4 +- src/esp/physics/bullet/BulletRigidObject.cpp | 3 +- src/esp/physics/bullet/BulletRigidStage.cpp | 2 +- src/esp/scene/SemanticScene.cpp | 2 +- src/esp/sim/Simulator.cpp | 24 +- src/tests/AttributesConfigsTest.cpp | 20 +- src/tests/MetadataMediatorTest.cpp | 12 +- src/tests/SimTest.cpp | 2 +- 21 files changed, 501 insertions(+), 192 deletions(-) diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index fd973445da..3227d510b6 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -312,7 +312,7 @@ bool ResourceManager::loadSemanticScene( semanticAttr, const std::string& activeSceneName) { const std::string ssdFilename = - semanticAttr != nullptr ? semanticAttr->getSemanticDescriptorFilename() + semanticAttr != nullptr ? semanticAttr->getSemanticDescriptorFullPath() : ""; semanticScene_ = nullptr; if ((ssdFilename != "") || ((semanticAttr != nullptr) && @@ -600,11 +600,11 @@ ResourceManager::createStageAssetInfosFromAttributes( // create render asset info AssetType renderType = stageAttributes->getRenderAssetType(); AssetInfo renderInfo{ - renderType, // type - stageAttributes->getRenderAssetHandle(), // file path - frame, // frame - virtualUnitToMeters, // virtualUnitToMeters - stageAttributes->getForceFlatShading() // forceFlatShading + renderType, // type + stageAttributes->getRenderAssetFullPath(), // file path + frame, // frame + virtualUnitToMeters, // virtualUnitToMeters + stageAttributes->getForceFlatShading() // forceFlatShading }; renderInfo.shaderTypeToUse = stageAttributes->getShaderType(); std::string debugStr{}; @@ -619,11 +619,11 @@ ResourceManager::createStageAssetInfosFromAttributes( // create collision asset info if requested AssetType colType = stageAttributes->getCollisionAssetType(); AssetInfo collisionInfo{ - colType, // type - stageAttributes->getCollisionAssetHandle(), // file path - frame, // frame - virtualUnitToMeters, // virtualUnitToMeters - true // forceFlatShading + colType, // type + stageAttributes->getCollisionAssetFullPath(), // file path + frame, // frame + virtualUnitToMeters, // virtualUnitToMeters + true // forceFlatShading }; // Only construct debug string if debug logging level is enabled if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::Debug)) { @@ -647,11 +647,11 @@ ResourceManager::createStageAssetInfosFromAttributes( stageAttributes->getOrigin()); } AssetInfo semanticInfo{ - semanticType, // type - stageAttributes->getSemanticAssetHandle(), // file path - frame, // frame - virtualUnitToMeters, // virtualUnitToMeters - true, // forceFlatShading + semanticType, // type + stageAttributes->getSemanticAssetFullPath(), // file path + frame, // frame + virtualUnitToMeters, // virtualUnitToMeters + true, // forceFlatShading // only split semantic mesh if doing frustum culling stageAttributes->getFrustumCulling() // splitInstanceMesh }; @@ -2896,7 +2896,7 @@ bool ResourceManager::instantiateAssetsOnDemand( } // get render asset handle - std::string renderAssetHandle = objectAttributes->getRenderAssetHandle(); + std::string renderAssetHandle = objectAttributes->getRenderAssetFullPath(); // whether attributes requires lighting bool forceFlatShading = objectAttributes->getForceFlatShading(); bool renderMeshSuccess = false; @@ -2930,7 +2930,7 @@ bool ResourceManager::instantiateAssetsOnDemand( // Probably just need to check attr->isCollidable() if (!objectAttributes->getCollisionAssetIsPrimitive()) { const auto collisionAssetHandle = - objectAttributes->getCollisionAssetHandle(); + objectAttributes->getCollisionAssetFullPath(); if (resourceDict_.count(collisionAssetHandle) == 0) { bool collisionMeshSuccess = loadObjectMeshDataFromFile( collisionAssetHandle, objectAttributes, "collision", @@ -3022,7 +3022,7 @@ void ResourceManager::addObjectToDrawables( //! Add mesh to rendering stack const std::string& renderObjectName = - ObjectAttributes->getRenderAssetHandle(); + ObjectAttributes->getRenderAssetFullPath(); RenderAssetInstanceCreationInfo::Flags flags; flags |= RenderAssetInstanceCreationInfo::Flag::IsRGBD; diff --git a/src/esp/metadata/MetadataMediator.cpp b/src/esp/metadata/MetadataMediator.cpp index d256ce861d..e67ca5bdfa 100644 --- a/src/esp/metadata/MetadataMediator.cpp +++ b/src/esp/metadata/MetadataMediator.cpp @@ -507,7 +507,7 @@ MetadataMediator::makeSceneAndReferenceStage( // by the ref that the scene attributes will use. std::pair navmeshEntry = datasetAttr->addNavmeshPathEntry( - sceneName, stageAttributes->getNavmeshAssetHandle(), false); + sceneName, stageAttributes->getNavmeshAssetFullPath(), false); // navmeshEntry holds the navmesh key-value in the dataset to use by this // scene instance. NOTE : the key may have changed from what was passed if a // collision occurred with same key but different value, so we need to add @@ -528,8 +528,8 @@ MetadataMediator::makeSceneAndReferenceStage( // add a ref to scene instance attributes of SemanticAttributes if any // Semantics info is specified in the passed stage stage, giving it an // appropriately obvious name. - if ((stageAttributes->getSemanticDescriptorFilename() != "") || - (stageAttributes->getSemanticAssetHandle() != "")) { + if ((stageAttributes->getSemanticDescriptorFullPath() != "") || + (stageAttributes->getSemanticAssetFullPath() != "")) { std::string sceneSemanticAttrHandle = datasetAttr->addSemanticSceneDescrPathEntry(sceneName, stageAttributes); diff --git a/src/esp/metadata/attributes/AbstractObjectAttributes.cpp b/src/esp/metadata/attributes/AbstractObjectAttributes.cpp index 619ca31d81..828ae95e3f 100644 --- a/src/esp/metadata/attributes/AbstractObjectAttributes.cpp +++ b/src/esp/metadata/attributes/AbstractObjectAttributes.cpp @@ -45,7 +45,9 @@ AbstractObjectAttributes::AbstractObjectAttributes( init("units_to_meters", 1.0); init("render_asset", ""); init("collision_asset", ""); - + // initialize these so they exist in Configuration + setHidden("__renderAssetFullPath", ""); + setHidden("__collisionAssetFullPath", ""); // This specifies that we want to investigate the state of the render and // collision handles before we allow this attributes to be registered. // Hidden field diff --git a/src/esp/metadata/attributes/ArticulatedObjectAttributes.cpp b/src/esp/metadata/attributes/ArticulatedObjectAttributes.cpp index 8ab3b85b31..c54dd4832b 100644 --- a/src/esp/metadata/attributes/ArticulatedObjectAttributes.cpp +++ b/src/esp/metadata/attributes/ArticulatedObjectAttributes.cpp @@ -37,6 +37,11 @@ ArticulatedObjectAttributes::ArticulatedObjectAttributes( init("uniform_scale", 1.0f); init("mass_scale", 1.0); + + // Initialize these so they exist in the configuration + setHidden("__urdfFullPath", ""); + setHidden("__renderAssetFullPath", ""); + // set up an existing subgroup for marker_sets attributes addOrEditSubgroup("marker_sets"); } // ArticulatedObjectAttributes ctor diff --git a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp index 0f3ec53c2b..1f724472de 100644 --- a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp +++ b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp @@ -153,8 +153,9 @@ void SceneDatasetAttributes::createSemanticAttribsFromDS( std::string SceneDatasetAttributes::addSemanticSceneDescrPathEntry( const std::string& semanticHandle, const attributes::StageAttributes::ptr& stageAttributes) { - const auto ssdFilename = stageAttributes->getSemanticDescriptorFilename(); - const auto semanticAssetFilename = stageAttributes->getSemanticAssetHandle(); + const auto ssdFilename = stageAttributes->getSemanticDescriptorFullPath(); + const auto semanticAssetFilename = + stageAttributes->getSemanticAssetFullPath(); bool setSemanticAssetData = (semanticAssetFilename != ""); bool setSSDFilename = (ssdFilename != ""); // create a semantic attributes if DNE with given handle @@ -164,16 +165,19 @@ std::string SceneDatasetAttributes::addSemanticSceneDescrPathEntry( auto semanticAttr = semanticAttributesManager_->getObjectByHandle(semanticHandle); - if (setSemanticAssetData && semanticAttr->getSemanticAssetHandle().empty()) { + if (setSemanticAssetData && + semanticAttr->getSemanticAssetFullPath().empty()) { // asset handle specified, get all stage-specified data - semanticAttr->setSemanticAssetHandle(semanticAssetFilename); + semanticAttr->setSemanticAssetHandle( + stageAttributes->getSemanticAssetHandle()); + semanticAttr->setSemanticAssetFullPath(semanticAssetFilename); semanticAttr->setSemanticAssetTypeEnum( stageAttributes->getSemanticAssetType()); semanticAttr->setSemanticOrientUp(stageAttributes->getSemanticOrientUp()); semanticAttr->setSemanticOrientFront( stageAttributes->getSemanticOrientFront()); } - if (setSSDFilename && semanticAttr->getSemanticDescriptorFilename().empty()) { + if (setSSDFilename && semanticAttr->getSemanticDescriptorFullPath().empty()) { // scene descriptor filename specified in stage, set in semantic // attributes. semanticAttr->setSemanticDescriptorFilename(ssdFilename); diff --git a/src/esp/metadata/attributes/SemanticAttributes.cpp b/src/esp/metadata/attributes/SemanticAttributes.cpp index b7dc3dd06c..00807fc733 100644 --- a/src/esp/metadata/attributes/SemanticAttributes.cpp +++ b/src/esp/metadata/attributes/SemanticAttributes.cpp @@ -63,8 +63,11 @@ void SemanticVolumeAttributes::writeValuesToJson( // SemanticAttributes SemanticAttributes::SemanticAttributes(const std::string& handle) : AbstractAttributes("SemanticAttributes", handle) { + // set empty defaults for handles init("semantic_descriptor_filename", ""); + setHidden("__semanticDescriptorFullPath", ""); init("semantic_asset", ""); + setHidden("__semanticAssetFullPath", ""); init("semantic_up", Mn::Vector3{0.0, 1.0, 0.0}); init("semantic_front", Mn::Vector3{0.0, 0.0, -1.0}); init("use_semantic_frame", false); diff --git a/src/esp/metadata/attributes/StageAttributes.cpp b/src/esp/metadata/attributes/StageAttributes.cpp index e83d891e52..01d4cd7f1d 100644 --- a/src/esp/metadata/attributes/StageAttributes.cpp +++ b/src/esp/metadata/attributes/StageAttributes.cpp @@ -28,8 +28,12 @@ StageAttributes::StageAttributes(const std::string& handle) initSemanticAssetTypeEnum(AssetType::InstanceMesh); // set empty defaults for handles init("nav_asset", ""); + setHidden("__navmeshAssetFullPath", ""); init("semantic_asset", ""); + setHidden("__semanticAssetFullPath", ""); init("semantic_descriptor_filename", ""); + setHidden("__semanticDescriptorFullPath", ""); + } // StageAttributes ctor void StageAttributes::writeValuesToJsonInternal( diff --git a/src/esp/metadata/managers/AOAttributesManager.cpp b/src/esp/metadata/managers/AOAttributesManager.cpp index c6bb5a7e94..fa61cefd63 100644 --- a/src/esp/metadata/managers/AOAttributesManager.cpp +++ b/src/esp/metadata/managers/AOAttributesManager.cpp @@ -121,21 +121,6 @@ AOAttributesManager::initNewObjectInternal(const std::string& attributesHandle, if (createNewAttributes) { newAttributes = attributes::ArticulatedObjectAttributes::create(attributesHandle); - // need to set base/default urdf_filepath to a valid potential filepath if - // a new attributes is being created here, to cover for older AO configs - // that may not reference their owning URDF files. This will only work for - // configs that reside in the same directory as their URDF counterparts. - - const auto urdfFilePath = newAttributes->getURDFPath(); - // If .urdf extension not found then replace with string with extension. - if (urdfFilePath.find(".urdf", urdfFilePath.length() - 5) == - std::string::npos) { - newAttributes->setURDFPath( - Cr::Utility::Path::splitExtension( - Cr::Utility::Path::splitExtension(urdfFilePath).first()) - .first() + - ".urdf"); - } } // set the attributes source filedirectory, from the attributes name this->setFileDirectoryFromHandle(newAttributes); @@ -156,7 +141,25 @@ AOAttributesManager::initNewObjectInternal(const std::string& attributesHandle, [newAttributes](const std::string& newHandle) { newAttributes->setRenderAssetHandle(newHandle); }); + } else { + // need to set base/default urdf_filepath to a valid potential + // filepath if a new attributes is being created here, to cover for older AO + // configs that may not reference their owning URDF files. This will only + // work for configs that reside in the same directory as their URDF + // counterparts. + + const auto urdfFilePath = newAttributes->getURDFPath(); + // If .urdf extension not found then replace with string with extension. + if (urdfFilePath.find(".urdf", urdfFilePath.length() - 5) == + std::string::npos) { + newAttributes->setURDFPath( + Cr::Utility::Path::splitExtension( + Cr::Utility::Path::splitExtension(urdfFilePath).first()) + .first() + + ".urdf"); + } } + // set default URDF filename - only set filename defaults if // attributesHandle is not a config file (which would never be a valid URDF // filename). Otherise, expect handles to be set when built from a config @@ -182,6 +185,7 @@ AOAttributesManager::preRegisterObjectFinalize( // ArticulatedObjectsAttributes must have a valid URDF_file it relates to or // it should not be registered. const std::string urdfFilePath = AOAttributesTemplate->getURDFPath(); + const std::string urdfFullFilePath = AOAttributesTemplate->getURDFFullPath(); if (urdfFilePath.empty()) { // URDF Filepath empty is bad ESP_ERROR(Mn::Debug::Flag::NoSpace) @@ -197,15 +201,30 @@ AOAttributesManager::preRegisterObjectFinalize( << "`, but this file cannot be found, so registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } + // URDF file this articulated object attributes references + this->filterAttribsFilenames( + AOAttributesTemplate, urdfFilePath, urdfFullFilePath, + [AOAttributesTemplate](const std::string& urdfAsset) { + AOAttributesTemplate->setURDFPath(urdfAsset); + }, + [AOAttributesTemplate](const std::string& urdfAsset) { + AOAttributesTemplate->setURDFFullPath(urdfAsset); + }); // Furthermore, if 'skin' is specified as render_mode and no skin is // specified or the specified skin cannot be found, the registration should // also fail and the template should not be registered. bool useSkinRenderMode = AOAttributesTemplate->getRenderMode() == attributes::ArticulatedObjectRenderMode::Skin; + std::string dispStr(""); if (useSkinRenderMode) { + // if 'skin' render mode is specified as render mode const std::string renderAssetHandle = AOAttributesTemplate->getRenderAssetHandle(); + + const std::string renderAssetFullPath = + AOAttributesTemplate->getRenderAssetFullPath(); + const std::string urdfSimpleName = Corrade::Utility::Path::splitExtension( Corrade::Utility::Path::splitExtension( @@ -223,6 +242,9 @@ AOAttributesManager::preRegisterObjectFinalize( "registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } else if (!Cr::Utility::Path::exists(renderAssetHandle)) { + // Otherwise, if renderAssetFullPath exists, this attributes is copy of an + // existing already-processed attributes with values set + // Skin render asset specified not found is bad when 'skin' render mode // is specified ESP_ERROR(Mn::Debug::Flag::NoSpace) @@ -234,9 +256,27 @@ AOAttributesManager::preRegisterObjectFinalize( << "` cannot be found, so registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } - } // if 'skin' render mode is specified as render mode + + // Render asset filename filter out path and set internal reference to + // full filepaath + this->filterAttribsFilenames( + AOAttributesTemplate, renderAssetHandle, renderAssetFullPath, + [AOAttributesTemplate](const std::string& renderAsset) { + AOAttributesTemplate->setRenderAssetHandle(renderAsset); + }, + [AOAttributesTemplate](const std::string& renderAsset) { + AOAttributesTemplate->setRenderAssetFullPath(renderAsset); + }); + + dispStr = Cr::Utility::formatString(" and render asset file path `{}`", + renderAssetHandle); + } + ESP_ERROR(Mn::Debug::Flag::NoSpace) + << "AO : `" << AOAttributesHandle << "` has urdf filename `" + << urdfFilePath << "`" << dispStr << "| file dir `" + << AOAttributesTemplate->getFileDirectory() << "`"; return core::managedContainers::ManagedObjectPreregistration::Success; -} // AOAttributesManager::registerObjectFinalize +} // AOAttributesManager::preRegisterObjectFinalize std::map AOAttributesManager::getArticulatedObjectModelFilenames() const { @@ -244,7 +284,7 @@ AOAttributesManager::getArticulatedObjectModelFilenames() const { for (const auto& val : this->objectLibrary_) { auto attr = this->getObjectByHandle(val.first); auto key = attr->getSimplifiedHandle(); - auto urdf = attr->getURDFPath(); + auto urdf = attr->getURDFFullPath(); articulatedObjPaths[key] = urdf; } return articulatedObjPaths; diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index 53c81992e4..794146efb7 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -15,6 +15,7 @@ #include "esp/io/Io.h" namespace Cr = Corrade; +namespace CrPath = Cr::Utility::Path; namespace esp { namespace core { @@ -224,7 +225,7 @@ class AttributesManager : public ManagedFileBasedContainer { * @return actual name of attributes in attrMgr, or empty string if does not * exist. */ - inline std::string getFullAttrNameFromStr(const std::string& attrName) { + inline std::string getFullAttrNameFromStr(const std::string& attrName) const { if (this->getObjectLibHasHandle(attrName)) { return attrName; } @@ -236,6 +237,70 @@ class AttributesManager : public ManagedFileBasedContainer { } // getFullAttrNameFromStr protected: + /** + * @brief Called internally right before attribute registration. Filepaths + * in the json configs for Habitat Datasets are specified relative to the + * location of the config in the file hierarchy. As the config is loaded, + * these filepaths will be fully qualified with absolute paths so that they + * can be easily found and consumed on command. However, saving fully + * qualified filepaths to JSON configs is undesirable. + * + * This function will query the passed @p attributes for a string using the + * @p relPathGetter to acquire the fully-qualified filename. It will set that + * value to be hidden in the attributes using @p fqPathSetter and then it will + * strip the attributes' filepath, if it is present, and set it as the + * relative value at @p relPathSetter . + * + * It is assumed that what is passed to this function always referneces a + * filepath, so if, for example, this is called on a render asseet filepath, + * it is assumed that that filepath does not reference a primitive + * (non-file-based) asset. + * + * @param attributes The Configuration-backed attributes owning the filepath + * in question. + * @param relPathGetter The relative filepath getter in the attributes + * @param relPathSetter The relative filepath setter in the attributes + * @param fqPathSetter The string tag for the filepath we want to be fully + * qualified. + */ + void filterAttribsFilenames( + const attributes::AbstractAttributes::ptr& attributes, + const std::function& relPathGetter, + const std::function& relPathSetter, + const std::function& fqPathSetter) const { + // Get the attributes filepath that our desired filepath should be relative + // to + std::string attrFilepath = attributes->getFileDirectory(); + // verify attributes filepath exists + if (CrPath::isDirectory(attrFilepath)) { + auto len = attrFilepath.length(); + // Get the filepath + std::string fqFilepath = relPathGetter(); + if (CrPath::exists(fqFilepath)) { + // Make sure attrFilepath is not longer than the filepath in + // question + if (len < fqFilepath.length()) { + if (fqFilepath.find(attrFilepath) != std::string::npos) { + // Set the fully qualified value + fqPathSetter(fqFilepath); + + ESP_ERROR() << "AttrHandle :" << attributes->getHandle() + << "|Getter result : " << fqFilepath + << " filepath :" << attrFilepath; + + auto relFilepath = std::string(fqFilepath); + // assume the undesired portion of the filepath always is at the + // beginning, adding 1 for the path separator + relFilepath.erase(0, len + 1); + // + relPathSetter(relFilepath); + } // if currently set relative handle contains filepath + } // if attributes dir is correct length + } // if relative filepath actually exists/is findable (i.e.is fully + // qualified) + } // if attributes dir is set properly + } // filterAttribsFilenames + /** * @brief Called intenrally from createObject. This will create either a * file based AbstractAttributes or a default one based on whether the @@ -359,14 +424,13 @@ std::vector AttributesManager::loadAllFileBasedTemplates( bool saveAsDefaults) { std::vector templateIndices(paths.size(), ID_UNDEFINED); if (paths.size() > 0) { - std::string dir = Cr::Utility::Path::split(paths[0]).first(); + std::string dir = CrPath::split(paths[0]).first(); ESP_DEBUG() << "Loading" << paths.size() << "" << this->objectType_ << "templates found in" << dir; for (int i = 0; i < paths.size(); ++i) { auto attributesFilename = paths[i]; - ESP_VERY_VERBOSE() - << "Load" << this->objectType_ << "template:" - << Cr::Utility::Path::split(attributesFilename).second(); + ESP_VERY_VERBOSE() << "Load" << this->objectType_ << "template:" + << CrPath::split(attributesFilename).second(); auto tmplt = this->createObject(attributesFilename, true); // If failed to load, do not attempt to modify further if (tmplt == nullptr) { @@ -458,10 +522,9 @@ void AttributesManager::buildAttrSrcPathsFromJSONAndLoad( // TODO Eventually we should normalize all metadata paths in the system std::string dsFilePath = - normalizePaths - ? Cr::Utility::Path::join(configDir.substr(0, cfgLastDirLoc), + normalizePaths ? CrPath::join(configDir.substr(0, cfgLastDirLoc), std::string(fileString).substr(3)) - : Cr::Utility::Path::join(configDir, fileString); + : CrPath::join(configDir, fileString); ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) << "<" << this->objectType_ << "> : Config dir : " << configDir @@ -503,7 +566,7 @@ auto AttributesManager::createFromJsonOrDefaultInternal( : this->getFormattedJSONFileName(filename)); // Check if this configuration file exists and if so use it to build // attributes - bool jsonFileExists = Cr::Utility::Path::exists(jsonAttrFileName); + bool jsonFileExists = CrPath::exists(jsonAttrFileName); ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) << "<" << this->objectType_ << ">: Proposing JSON name `" << jsonAttrFileName << "` from original name `" << filename @@ -520,7 +583,7 @@ auto AttributesManager::createFromJsonOrDefaultInternal( // default attributes. attrs = this->createDefaultObject(filename, registerObj); // check if original filename is an actual object - bool fileExists = Cr::Utility::Path::exists(filename); + bool fileExists = CrPath::exists(filename); // if filename passed is name of some kind of asset, or if it was not // found if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::Debug)) { @@ -583,7 +646,7 @@ bool AttributesManager::setFilenameFromDefaultTag( } // First check if tag references a file that already exists on disk and is // able to be found - if (Cr::Utility::Path::exists(srcAssetFilename)) { + if (CrPath::exists(srcAssetFilename)) { // set filename with verified filepath filenameSetter(srcAssetFilename); return true; @@ -596,14 +659,14 @@ bool AttributesManager::setFilenameFromDefaultTag( // not. tempStr.replace(loc, strlen(CONFIG_NAME_AS_ASSET_FILENAME), attributes->getSimplifiedHandle()); - if (Cr::Utility::Path::exists(tempStr)) { + if (CrPath::exists(tempStr)) { // replace the component of the string containing the tag with the base // filename/handle, and verify it exists. Otherwise, clear it. filenameSetter(tempStr); return true; } - tempStr = Cr::Utility::Path::join(attributes->getFileDirectory(), tempStr); - if (Cr::Utility::Path::exists(tempStr)) { + tempStr = CrPath::join(attributes->getFileDirectory(), tempStr); + if (CrPath::exists(tempStr)) { // replace the component of the string containing the tag with the base // filename/handle, and verify it exists. Otherwise, clear it. filenameSetter(tempStr); @@ -616,8 +679,8 @@ bool AttributesManager::setFilenameFromDefaultTag( } // no sentinel tag found - check if existing non-empty field exists. std::string tempStr = - Cr::Utility::Path::join(attributes->getFileDirectory(), srcAssetFilename); - if (Cr::Utility::Path::exists(tempStr)) { + CrPath::join(attributes->getFileDirectory(), srcAssetFilename); + if (CrPath::exists(tempStr)) { // path-prefixed filename exists on disk, so set as filename filenameSetter(tempStr); return true; diff --git a/src/esp/metadata/managers/ObjectAttributesManager.cpp b/src/esp/metadata/managers/ObjectAttributesManager.cpp index 86f1c73f16..84eeaefc71 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.cpp +++ b/src/esp/metadata/managers/ObjectAttributesManager.cpp @@ -223,15 +223,20 @@ ObjectAttributesManager::preRegisterObjectFinalize( // Handles for rendering and collision assets std::string renderAssetHandle = objectTemplate->getRenderAssetHandle(); + std::string renderAssetFullPath = objectTemplate->getRenderAssetFullPath(); std::string collisionAssetHandle = objectTemplate->getCollisionAssetHandle(); + std::string collisionAssetFullPath = + objectTemplate->getCollisionAssetFullPath(); + // Clear map to add to ptr from previous registration mapToAddTo_ = nullptr; - + // verify these represent legitimate assets if (this->isValidPrimitiveAttributes(renderAssetHandle)) { // If renderAssetHandle corresponds to valid/existing primitive attributes // then setRenderAssetIsPrimitive to true and set map of IDs->Names to // physicsSynthObjTmpltLibByID_ objectTemplate->setRenderAssetIsPrimitive(true); + objectTemplate->setRenderAssetFullPath(renderAssetHandle); mapToAddTo_ = &physicsSynthObjTmpltLibByID_; } else if (Cr::Utility::Path::exists(renderAssetHandle)) { // Check if renderAssetHandle is valid file name and is found in file system @@ -239,6 +244,27 @@ ObjectAttributesManager::preRegisterObjectFinalize( // to physicsFileObjTmpltLibByID_ - verify file exists objectTemplate->setRenderAssetIsPrimitive(false); mapToAddTo_ = &physicsFileObjTmpltLibByID_; + // Render asset filename filter out path and set internal reference to full + // filepaath + this->filterAttribsFilenames( + objectTemplate, + [objectTemplate](void) -> std::string { + return objectTemplate->getRenderAssetHandle(); + }, + [objectTemplate](const std::string& renderAsset) { + objectTemplate->setRenderAssetHandle(renderAsset); + }, + [objectTemplate](const std::string& renderAsset) { + objectTemplate->setRenderAssetFullPath(renderAsset); + }); + // Re-set to catch path removal. + renderAssetHandle = objectTemplate->getRenderAssetHandle(); + + } else if (Cr::Utility::Path::exists(renderAssetFullPath)) { + // not prim and does not exist on disk, perhaps the fully qualified version + // of the handle was set already and exists, which means we don't need to do + // anything else. + objectTemplate->setRenderAssetIsPrimitive(false); } else if (forceRegistration) { // Forcing registration in case of computationaly generated assets ESP_WARNING(Mn::Debug::Flag::NoSpace) @@ -265,10 +291,31 @@ ObjectAttributesManager::preRegisterObjectFinalize( // If collisionAssetHandle corresponds to valid/existing primitive // attributes then setCollisionAssetIsPrimitive to true objectTemplate->setCollisionAssetIsPrimitive(true); + objectTemplate->setCollisionAssetFullPath(collisionAssetHandle); } else if (Cr::Utility::Path::exists(collisionAssetHandle)) { // Check if collisionAssetHandle is valid file name and is found in file // system - if so then setCollisionAssetIsPrimitive to false objectTemplate->setCollisionAssetIsPrimitive(false); + + // Collision asset filename filter out path and set internal reference to + // full filepaath + this->filterAttribsFilenames( + objectTemplate, + [objectTemplate](void) -> std::string { + return objectTemplate->getCollisionAssetHandle(); + }, + [objectTemplate](const std::string& colHndl) { + objectTemplate->setCollisionAssetHandle(colHndl); + }, + [objectTemplate](const std::string& colHndl) { + objectTemplate->setCollisionAssetFullPath(colHndl); + }); + + } else if (Cr::Utility::Path::exists(collisionAssetFullPath)) { + // not prim and does not exist on disk, perhaps the fully qualified version + // of the handle was set already and exists, which means we don't need to do + // anything else. + objectTemplate->setCollisionAssetIsPrimitive(false); } else { // Else, means no collision data specified, use specified render data ESP_DEBUG(Mn::Debug::Flag::NoSpace) @@ -277,12 +324,22 @@ ObjectAttributesManager::preRegisterObjectFinalize( << "` does not correspond to any existing file or primitive render " "asset. Overriding with given render asset handle :" << renderAssetHandle << "."; + // Set values to match render asset values objectTemplate->setCollisionAssetHandle(renderAssetHandle); + objectTemplate->setCollisionAssetFullPath( + objectTemplate->getRenderAssetFullPath()); + objectTemplate->setCollisionAssetIsPrimitive( objectTemplate->getRenderAssetIsPrimitive()); } + // ESP_ERROR(Mn::Debug::Flag::NoSpace) + // << "Obj `" << objectTemplateHandle << "`: Render fn `" + // << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" + // << objectTemplate->getCollisionAssetHandle() << "`| file dir `" + // << objectTemplate->getFileDirectory() << "`"; + // Clear dirty flag from when asset handles are changed objectTemplate->setIsClean(); diff --git a/src/esp/metadata/managers/SemanticAttributesManager.cpp b/src/esp/metadata/managers/SemanticAttributesManager.cpp index 538c3abca6..57da1f7628 100644 --- a/src/esp/metadata/managers/SemanticAttributesManager.cpp +++ b/src/esp/metadata/managers/SemanticAttributesManager.cpp @@ -218,6 +218,47 @@ void SemanticAttributesManager::setValsFromJSONDoc( } // SemanticAttributesManager::setValsFromJSONDoc +core::managedContainers::ManagedObjectPreregistration +SemanticAttributesManager::preRegisterObjectFinalize( + attributes::SemanticAttributes::ptr semanticAttributes, + const std::string& semanticAttrHandle, + CORRADE_UNUSED bool forceRegistration) { + // filter filepaths of full path qualifiers + // Semantic asset filename + this->filterAttribsFilenames( + semanticAttributes, + [semanticAttributes](void) -> std::string { + return semanticAttributes->getSemanticAssetHandle(); + }, + [semanticAttributes](const std::string& semanticAsset) { + semanticAttributes->setSemanticAssetHandle(semanticAsset); + }, + [semanticAttributes](const std::string& semanticAsset) { + semanticAttributes->setSemanticAssetFullPath(semanticAsset); + }); + // Semantic descriptor filename + this->filterAttribsFilenames( + semanticAttributes, + [semanticAttributes](void) -> std::string { + return semanticAttributes->getSemanticDescriptorFilename(); + }, + [semanticAttributes](const std::string& semanticAsset) { + semanticAttributes->setSemanticDescriptorFilename(semanticAsset); + }, + [semanticAttributes](const std::string& semanticAsset) { + semanticAttributes->setSemanticDescriptorFullPath(semanticAsset); + }); + + ESP_ERROR(Mn::Debug::Flag::NoSpace) + << "Semantic Attr `" << semanticAttrHandle << "`| semantic asset fn `" + << semanticAttributes->getSemanticAssetHandle() + << "`| semantic descriptor fn `" + << semanticAttributes->getSemanticDescriptorFilename() << "`| file dir `" + << semanticAttributes->getFileDirectory() << "`"; + // No pre-registration conditioning performed + return core::managedContainers::ManagedObjectPreregistration::Success; +} + } // namespace managers } // namespace metadata } // namespace esp diff --git a/src/esp/metadata/managers/SemanticAttributesManager.h b/src/esp/metadata/managers/SemanticAttributesManager.h index 5bae7af467..c4fe73c4ec 100644 --- a/src/esp/metadata/managers/SemanticAttributesManager.h +++ b/src/esp/metadata/managers/SemanticAttributesManager.h @@ -124,11 +124,9 @@ class SemanticAttributesManager CORRADE_UNUSED const std::string& templateHandle) override {} /** - * @brief Not required for this manager. - * - * This method will perform any essential updating to the managed object - * before registration is performed. If this updating fails, registration will - * also fail. + * @brief This method will perform any essential updating to the managed + * object before registration is performed. If this updating fails, + * registration will also fail. * @param object the managed object to be registered * @param objectHandle the name to register the managed object with. * Expected to be valid. @@ -138,13 +136,9 @@ class SemanticAttributesManager * register the object if it has. */ core::managedContainers::ManagedObjectPreregistration - preRegisterObjectFinalize( - CORRADE_UNUSED attributes::SemanticAttributes::ptr object, - CORRADE_UNUSED const std::string& objectHandle, - CORRADE_UNUSED bool forceRegistration) override { - // No pre-registration conditioning performed - return core::managedContainers::ManagedObjectPreregistration::Success; - } + preRegisterObjectFinalize(attributes::SemanticAttributes::ptr object, + const std::string& objectHandle, + CORRADE_UNUSED bool forceRegistration) override; /** * @brief Not required for this manager. diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index e257a1986b..82320e3433 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -45,90 +45,6 @@ void StageAttributesManager::createDefaultPrimBasedAttributesTemplates() { this->undeletableObjectNames_.insert(std::move(tmpltHandle)); } // StageAttributesManager::createDefaultPrimBasedAttributesTemplates -core::managedContainers::ManagedObjectPreregistration -StageAttributesManager::preRegisterObjectFinalize( - StageAttributes::ptr stageAttributes, - const std::string& stageAttributesHandle, - bool forceRegistration) { - if (stageAttributes->getRenderAssetHandle().empty()) { - ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "Attributes template named `" << stageAttributesHandle - << "` does not have a valid render asset handle specified, so " - "StageAttributes registration is aborted."; - return core::managedContainers::ManagedObjectPreregistration::Failed; - } - - // Handles for rendering and collision assets - std::string renderAssetHandle = stageAttributes->getRenderAssetHandle(); - std::string collisionAssetHandle = stageAttributes->getCollisionAssetHandle(); - - // verify these represent legitimate assets - if (StageAttributesManager::isValidPrimitiveAttributes(renderAssetHandle)) { - // If renderAssetHandle corresponds to valid/existing primitive attributes - // then setRenderAssetIsPrimitive to true and set map of IDs->Names to - // physicsSynthObjTmpltLibByID_ - stageAttributes->setRenderAssetIsPrimitive(true); - } else if (Cr::Utility::Path::exists(renderAssetHandle)) { - // Check if renderAssetHandle is valid file name and is found in file - // system - // - if so then setRenderAssetIsPrimitive to false and set map of - // IDs->Names to physicsFileObjTmpltLibByID_ - verify file exists - stageAttributes->setRenderAssetIsPrimitive(false); - } else if (std::string::npos != stageAttributesHandle.find("NONE")) { - // Render asset handle will be NONE as well - force type to be unknown - stageAttributes->setRenderAssetTypeEnum(AssetType::Unknown); - stageAttributes->setRenderAssetIsPrimitive(false); - } else if (forceRegistration) { - ESP_WARNING() - << "Render asset template handle :" << renderAssetHandle - << "specified in stage template with handle `" << stageAttributesHandle - << "` does not correspond to any existing file or primitive render " - "asset. This attributes is not in a valid state."; - } else { - // If renderAssetHandle is not valid file name needs to fail - ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "Render asset template handle `" << renderAssetHandle - << "` specified in stage template with handle :" - << stageAttributesHandle - << "does not correspond to any existing file or primitive render " - "asset, so StageAttributes registration is aborted."; - return core::managedContainers::ManagedObjectPreregistration::Failed; - } - - if (StageAttributesManager::isValidPrimitiveAttributes( - collisionAssetHandle)) { - // If collisionAssetHandle corresponds to valid/existing primitive - // attributes then setCollisionAssetIsPrimitive to true - stageAttributes->setCollisionAssetIsPrimitive(true); - } else if (Cr::Utility::Path::exists(collisionAssetHandle)) { - // Check if collisionAssetHandle is valid file name and is found in file - // system - if so then setCollisionAssetIsPrimitive to false - stageAttributes->setCollisionAssetIsPrimitive(false); - } else if (std::string::npos != stageAttributesHandle.find("NONE")) { - // Collision asset handle will be NONE as well - force type to be unknown - stageAttributes->setCollisionAssetType( - getAssetTypeName(AssetType::Unknown)); - stageAttributes->setCollisionAssetIsPrimitive(false); - } else { - // Else, means no collision data specified, use specified render data - ESP_DEBUG() - << "Collision asset template handle :" << collisionAssetHandle - << "specified in stage template with handle :" << stageAttributesHandle - << "does not correspond to any existing file or primitive render " - "asset. Overriding with given render asset handle :" - << renderAssetHandle << "."; - - stageAttributes->setCollisionAssetHandle(renderAssetHandle); - stageAttributes->setCollisionAssetIsPrimitive( - stageAttributes->getRenderAssetIsPrimitive()); - } - // Clear dirty flag from when asset handles are changed - stageAttributes->setIsClean(); - - return core::managedContainers::ManagedObjectPreregistration::Success; - -} // StageAttributesManager::registerAttributesTemplate - StageAttributes::ptr StageAttributesManager::createPrimBasedAttributesTemplate( const std::string& primAssetHandle, bool registerTemplate) { @@ -348,7 +264,7 @@ void StageAttributesManager::setDefaultAssetNameBasedAttributes( // coordinate frame to -Z gravity up = up2; fwd = fwd2; - } else if (StageAttributesManager::isValidPrimitiveAttributes(fileName)) { + } else if (this->isValidPrimitiveAttributes(fileName)) { assetTypeSetter(AssetType::Primitive); } else { assetTypeSetter(AssetType::Unknown); @@ -450,6 +366,181 @@ void StageAttributesManager::setValsFromJSONDoc( } // StageAttributesManager::setValsFromJSONDoc +core::managedContainers::ManagedObjectPreregistration +StageAttributesManager::preRegisterObjectFinalize( + StageAttributes::ptr stageAttributes, + const std::string& stageAttributesHandle, + bool forceRegistration) { + if (stageAttributes->getRenderAssetHandle().empty()) { + ESP_ERROR(Mn::Debug::Flag::NoSpace) + << "Attributes template named `" << stageAttributesHandle + << "` does not have a valid render asset handle specified, so " + "StageAttributes registration is aborted."; + return core::managedContainers::ManagedObjectPreregistration::Failed; + } + + // Handles for rendering and collision assets + std::string renderAssetHandle = stageAttributes->getRenderAssetHandle(); + std::string renderAssetFullPath = stageAttributes->getRenderAssetFullPath(); + std::string collisionAssetHandle = stageAttributes->getCollisionAssetHandle(); + std::string collisionAssetFullPath = + stageAttributes->getCollisionAssetFullPath(); + bool stageIsNone = stageAttributesHandle.find("NONE") != std::string::npos; + // verify these represent legitimate assets + if (this->isValidPrimitiveAttributes(renderAssetHandle)) { + // If renderAssetHandle corresponds to valid/existing primitive attributes + // then setRenderAssetIsPrimitive to true and set map of IDs->Names to + // physicsSynthObjTmpltLibByID_ + stageAttributes->setRenderAssetIsPrimitive(true); + stageAttributes->setRenderAssetFullPath(renderAssetHandle); + } else if (Cr::Utility::Path::exists(renderAssetHandle)) { + // Check if renderAssetHandle is valid file name and is found in file + // system - if so then setRenderAssetIsPrimitive to false and set map of + // IDs->Names to physicsFileObjTmpltLibByID_ - verify file exists + stageAttributes->setRenderAssetIsPrimitive(false); + // Render asset filename filter out path and set internal reference to full + // filepaath + this->filterAttribsFilenames( + stageAttributes, + [stageAttributes](void) -> std::string { + return stageAttributes->getRenderAssetHandle(); + }, + [stageAttributes](const std::string& renderAsset) { + stageAttributes->setRenderAssetHandle(renderAsset); + }, + [stageAttributes](const std::string& renderAsset) { + stageAttributes->setRenderAssetFullPath(renderAsset); + }); + // Re-set to catch path removal. + renderAssetHandle = stageAttributes->getRenderAssetHandle(); + } else if (Cr::Utility::Path::exists(renderAssetFullPath)) { + // not prim and does not exist on disk, perhaps the fully qualified version + // of the handle was set already and exists, which means we don't need to do + // anything else. + stageAttributes->setRenderAssetIsPrimitive(false); + } else if (stageIsNone) { + // Render asset handle will be NONE as well - force type to be unknown + stageAttributes->setRenderAssetTypeEnum(AssetType::Unknown); + stageAttributes->setRenderAssetIsPrimitive(false); + stageAttributes->setRenderAssetFullPath("NONE"); + } else if (forceRegistration) { + ESP_WARNING() + << "Render asset template handle :" << renderAssetHandle + << "specified in stage template with handle `" << stageAttributesHandle + << "` does not correspond to any existing file or primitive render " + "asset. This attributes is not in a valid state."; + } else { + // If renderAssetHandle is not valid file name needs to fail + ESP_ERROR(Mn::Debug::Flag::NoSpace) + << "Render asset template handle `" << renderAssetHandle + << "` specified in stage template with handle :" + << stageAttributesHandle + << "does not correspond to any existing file or primitive render " + "asset, so StageAttributes registration is aborted."; + return core::managedContainers::ManagedObjectPreregistration::Failed; + } + + if (this->isValidPrimitiveAttributes(collisionAssetHandle)) { + // If collisionAssetHandle corresponds to valid/existing primitive + // attributes then setCollisionAssetIsPrimitive to true + stageAttributes->setCollisionAssetIsPrimitive(true); + stageAttributes->setCollisionAssetFullPath(collisionAssetHandle); + } else if (Cr::Utility::Path::exists(collisionAssetHandle)) { + // Check if collisionAssetHandle is valid file name and is found in file + // system - if so then setCollisionAssetIsPrimitive to false + stageAttributes->setCollisionAssetIsPrimitive(false); + // Collision asset filename filter out path and set internal reference to + // full filepaath + this->filterAttribsFilenames( + stageAttributes, + [stageAttributes](void) -> std::string { + return stageAttributes->getCollisionAssetHandle(); + }, + [stageAttributes](const std::string& colHndl) { + stageAttributes->setCollisionAssetHandle(colHndl); + }, + [stageAttributes](const std::string& colHndl) { + stageAttributes->setCollisionAssetFullPath(colHndl); + }); + } else if (Cr::Utility::Path::exists(collisionAssetFullPath)) { + // not prim and does not exist on disk, perhaps the fully qualified version + // of the handle was set already and exists, which means we don't need to do + // anything else. + stageAttributes->setCollisionAssetIsPrimitive(false); + } else if (std::string::npos != stageAttributesHandle.find("NONE")) { + // Collision asset handle will be NONE as well - force type to be unknown + stageAttributes->setCollisionAssetType( + getAssetTypeName(AssetType::Unknown)); + stageAttributes->setCollisionAssetIsPrimitive(false); + stageAttributes->setCollisionAssetFullPath("NONE"); + } else { + // Else, means no collision data specified, use specified render data + ESP_DEBUG() + << "Collision asset template handle :" << collisionAssetHandle + << "specified in stage template with handle :" << stageAttributesHandle + << "does not correspond to any existing file or primitive render " + "asset. Overriding with given render asset handle :" + << renderAssetHandle << "."; + + stageAttributes->setCollisionAssetHandle(renderAssetHandle); + stageAttributes->setCollisionAssetIsPrimitive( + stageAttributes->getRenderAssetIsPrimitive()); + } + // filter filepaths of full path qualifiers + // Navmesh asset filename + this->filterAttribsFilenames( + stageAttributes, + [stageAttributes](void) -> std::string { + return stageAttributes->getNavmeshAssetHandle(); + }, + [stageAttributes](const std::string& semanticAsset) { + stageAttributes->setNavmeshAssetHandle(semanticAsset); + }, + [stageAttributes](const std::string& semanticAsset) { + stageAttributes->setNavmeshAssetFullPath(semanticAsset); + }); + // Semantic asset filename + this->filterAttribsFilenames( + stageAttributes, + [stageAttributes](void) -> std::string { + return stageAttributes->getSemanticAssetHandle(); + }, + [stageAttributes](const std::string& semanticAsset) { + stageAttributes->setSemanticAssetHandle(semanticAsset); + }, + [stageAttributes](const std::string& semanticAsset) { + stageAttributes->setSemanticAssetFullPath(semanticAsset); + }); + // Semantic descriptor filename + this->filterAttribsFilenames( + stageAttributes, + [stageAttributes](void) -> std::string { + return stageAttributes->getSemanticDescriptorFilename(); + }, + [stageAttributes](const std::string& semanticAsset) { + stageAttributes->setSemanticDescriptorFilename(semanticAsset); + }, + [stageAttributes](const std::string& semanticAsset) { + stageAttributes->setSemanticDescriptorFullPath(semanticAsset); + }); + + ESP_ERROR(Mn::Debug::Flag::NoSpace) + << "Stage `" << stageAttributesHandle << "`: Render fn `" + << stageAttributes->getRenderAssetHandle() << "`| Collision fn `" + << stageAttributes->getCollisionAssetHandle() << "`| navmesh fn `" + << stageAttributes->getNavmeshAssetHandle() << "`| semantic asset fn `" + << stageAttributes->getSemanticAssetHandle() + << "`| semantic descriptor fn `" + << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" + << stageAttributes->getFileDirectory() << "`"; + + // Clear dirty flag from when asset handles are changed + stageAttributes->setIsClean(); + + return core::managedContainers::ManagedObjectPreregistration::Success; + +} // StageAttributesManager::registerAttributesTemplate + } // namespace managers } // namespace metadata } // namespace esp diff --git a/src/esp/physics/bullet/BulletPhysicsManager.cpp b/src/esp/physics/bullet/BulletPhysicsManager.cpp index 350ebcdd9c..2a1471a3ae 100644 --- a/src/esp/physics/bullet/BulletPhysicsManager.cpp +++ b/src/esp/physics/bullet/BulletPhysicsManager.cpp @@ -126,7 +126,7 @@ int BulletPhysicsManager::addArticulatedObjectInternal( // acquire context if available simulator_->getRenderGLContext(); } - const std::string urdfFilepath = artObjAttributes->getURDFPath(); + const std::string urdfFilepath = artObjAttributes->getURDFFullPath(); // Load model and set active ESP_CHECK(urdfImporter_->loadURDF(urdfFilepath, forceReload), "failed to parse/load URDF file" << urdfFilepath); @@ -155,7 +155,7 @@ int BulletPhysicsManager::addArticulatedObjectInternal( auto model = u2b->getModel(); // if the AO attributes specifies a render asset, load and link it - const auto renderAssetPath = artObjAttributes->getRenderAssetHandle(); + const auto renderAssetPath = artObjAttributes->getRenderAssetFullPath(); if (renderAssetPath != "") { instantiateSkinnedModel(articulatedObject, artObjAttributes, renderAssetPath, objectNode, drawables, lightSetup); diff --git a/src/esp/physics/bullet/BulletRigidObject.cpp b/src/esp/physics/bullet/BulletRigidObject.cpp index 189635463c..500e93538e 100644 --- a/src/esp/physics/bullet/BulletRigidObject.cpp +++ b/src/esp/physics/bullet/BulletRigidObject.cpp @@ -97,7 +97,8 @@ bool BulletRigidObject::constructCollisionShape() { auto initAttr = PhysicsObjectBase::getInitializationAttributes< metadata::attributes::ObjectAttributes>(); // collision mesh/asset handle - const std::string collisionAssetHandle = initAttr->getCollisionAssetHandle(); + const std::string collisionAssetHandle = + initAttr->getCollisionAssetFullPath(); if (!initAttr->getUseMeshCollision()) { // if using prim collider get appropriate bullet collision primitive diff --git a/src/esp/physics/bullet/BulletRigidStage.cpp b/src/esp/physics/bullet/BulletRigidStage.cpp index ddd288b60e..d58dbbfbf4 100644 --- a/src/esp/physics/bullet/BulletRigidStage.cpp +++ b/src/esp/physics/bullet/BulletRigidStage.cpp @@ -70,7 +70,7 @@ void BulletRigidStage::constructAndAddCollisionObjects() { auto initAttr = PhysicsObjectBase::getInitializationAttributes< metadata::attributes::StageAttributes>(); // construct the objects first time - const auto collisionAssetHandle = initAttr->getCollisionAssetHandle(); + const auto collisionAssetHandle = initAttr->getCollisionAssetFullPath(); const std::vector& meshGroup = resMgr_.getCollisionMesh(collisionAssetHandle); diff --git a/src/esp/scene/SemanticScene.cpp b/src/esp/scene/SemanticScene.cpp index 6f70482e9d..f7403cd3c6 100644 --- a/src/esp/scene/SemanticScene.cpp +++ b/src/esp/scene/SemanticScene.cpp @@ -26,7 +26,7 @@ namespace scene { bool SemanticScene:: loadSemanticSceneDescriptor(const std::shared_ptr& semanticAttr, SemanticScene& scene, const quatf& rotation /* = quatf::FromTwoVectors(-vec3f::UnitZ(), geo::ESP_GRAVITY) */) { const std::string ssdFileName = - semanticAttr != nullptr ? semanticAttr->getSemanticDescriptorFilename() + semanticAttr != nullptr ? semanticAttr->getSemanticDescriptorFullPath() : ""; bool loadSuccess = false; diff --git a/src/esp/sim/Simulator.cpp b/src/esp/sim/Simulator.cpp index 95617ab7a2..3bd7d40917 100644 --- a/src/esp/sim/Simulator.cpp +++ b/src/esp/sim/Simulator.cpp @@ -498,16 +498,20 @@ bool Simulator::instanceStageForSceneAttributes( // SemanticAttributes if (semanticAttr != nullptr) { const std::string semanticAttrSSDName = - semanticAttr->getSemanticDescriptorFilename(); + semanticAttr->getSemanticDescriptorFullPath(); const std::string semanticAttrAssetName = - semanticAttr->getSemanticAssetHandle(); + semanticAttr->getSemanticAssetFullPath(); // - Set stage semantic values if appropriate - this overrides whatever is // specified previoussly in stage attributes. if (semanticAttrSSDName != "") { - stageAttributes->setSemanticDescriptorFilename(semanticAttrSSDName); + stageAttributes->setSemanticDescriptorFilename( + semanticAttr->getSemanticDescriptorFilename()); + stageAttributes->setSemanticDescriptorFullPath(semanticAttrSSDName); } if (semanticAttrAssetName != "") { - stageAttributes->setSemanticAssetHandle(semanticAttrAssetName); + stageAttributes->setSemanticAssetHandle( + semanticAttr->getSemanticAssetHandle()); + stageAttributes->setSemanticAssetFullPath(semanticAttrAssetName); stageAttributes->setSemanticAssetTypeEnum( semanticAttr->getSemanticAssetType()); if (semanticAttr->getSemanticOrientFront() != @@ -534,9 +538,9 @@ bool Simulator::instanceStageForSceneAttributes( std::vector tempIDs{activeSceneID_, activeSemanticSceneID_}; ESP_DEBUG() << "Start to load stage named :" << stageAttributes->getHandle() << "with render asset :" - << stageAttributes->getRenderAssetHandle() + << stageAttributes->getRenderAssetFullPath() << "and collision asset :" - << stageAttributes->getCollisionAssetHandle(); + << stageAttributes->getCollisionAssetFullPath(); // Load stage bool loadSuccess = resourceManager_->loadStage( @@ -883,7 +887,7 @@ assets::MeshData::ptr Simulator::getJoinedMesh( auto stageInitAttrs = physicsManager_->getStageInitAttributes(); if (stageInitAttrs != nullptr) { joinedMesh = resourceManager_->createJoinedCollisionMesh( - stageInitAttrs->getRenderAssetHandle()); + stageInitAttrs->getRenderAssetFullPath()); } // add STATIC collision objects @@ -915,9 +919,9 @@ assets::MeshData::ptr Simulator::getJoinedMesh( objectTransform.scale(Magnum::EigenIntegration::cast( initializationTemplate->getScale())); std::string meshHandle = - initializationTemplate->getCollisionAssetHandle(); + initializationTemplate->getCollisionAssetFullPath(); if (meshHandle.empty()) { - meshHandle = initializationTemplate->getRenderAssetHandle(); + meshHandle = initializationTemplate->getRenderAssetFullPath(); } meshComponentStates[meshHandle].push_back(objectTransform); } @@ -981,7 +985,7 @@ assets::MeshData::ptr Simulator::getJoinedSemanticMesh( auto stageInitAttrs = physicsManager_->getStageInitAttributes(); if (stageInitAttrs != nullptr) { joinedSemanticMesh = resourceManager_->createJoinedSemanticCollisionMesh( - objectIds, stageInitAttrs->getSemanticAssetHandle()); + objectIds, stageInitAttrs->getSemanticAssetFullPath()); } return joinedSemanticMesh; diff --git a/src/tests/AttributesConfigsTest.cpp b/src/tests/AttributesConfigsTest.cpp index ac5929fe07..87f90a2fd4 100644 --- a/src/tests/AttributesConfigsTest.cpp +++ b/src/tests/AttributesConfigsTest.cpp @@ -1134,11 +1134,11 @@ void AttributesConfigsTest::testSemanticAttrVals( std::shared_ptr semanticAttr, const std::string& assetPath) { CORRADE_COMPARE( - semanticAttr->getSemanticDescriptorFilename(), + semanticAttr->getSemanticDescriptorFullPath(), Cr::Utility::Path::join(assetPath, "test_semantic_lexicon.json")); CORRADE_COMPARE( - semanticAttr->getSemanticAssetHandle(), + semanticAttr->getSemanticAssetFullPath(), Cr::Utility::Path::join(assetPath, "test_semantic_asset.glb")); // verify regions @@ -1319,8 +1319,8 @@ void AttributesConfigsTest::testStageAttrVals( Mn::Vector3(2.0, 0.0, 0.0)); CORRADE_COMPARE(stageAttr->getSemanticOrientUp(), Mn::Vector3(0.0, 2.0, 0.0)); - CORRADE_COMPARE(stageAttr->getRenderAssetHandle(), assetPath); - CORRADE_COMPARE(stageAttr->getCollisionAssetHandle(), assetPath); + CORRADE_COMPARE(stageAttr->getRenderAssetFullPath(), assetPath); + CORRADE_COMPARE(stageAttr->getCollisionAssetFullPath(), assetPath); CORRADE_VERIFY(!stageAttr->getIsCollidable()); // stage-specific attributes CORRADE_COMPARE(stageAttr->getOrigin(), Mn::Vector3(1, 2, 3)); @@ -1330,8 +1330,8 @@ void AttributesConfigsTest::testStageAttrVals( // make sure that is not default value "flat" CORRADE_COMPARE(static_cast(stageAttr->getShaderType()), static_cast(Attrs::ObjectInstanceShaderType::Material)); - CORRADE_COMPARE(stageAttr->getSemanticAssetHandle(), assetPath); - CORRADE_COMPARE(stageAttr->getNavmeshAssetHandle(), assetPath); + CORRADE_COMPARE(stageAttr->getSemanticAssetFullPath(), assetPath); + CORRADE_COMPARE(stageAttr->getNavmeshAssetFullPath(), assetPath); // test stage attributes-level user config vals testUserDefinedConfigVals( stageAttr->getUserConfiguration(), 4, "stage defined string", false, 3, @@ -1592,8 +1592,8 @@ void AttributesConfigsTest::testObjectAttrVals( CORRADE_COMPARE(objAttr->getUnitsToMeters(), 1.1); CORRADE_COMPARE(objAttr->getOrientUp(), Mn::Vector3(2.1, 0, 0)); CORRADE_COMPARE(objAttr->getOrientFront(), Mn::Vector3(0, 2.1, 0)); - CORRADE_COMPARE(objAttr->getRenderAssetHandle(), assetPath); - CORRADE_COMPARE(objAttr->getCollisionAssetHandle(), assetPath); + CORRADE_COMPARE(objAttr->getRenderAssetFullPath(), assetPath); + CORRADE_COMPARE(objAttr->getCollisionAssetFullPath(), assetPath); CORRADE_VERIFY(!objAttr->getIsCollidable()); CORRADE_COMPARE(objAttr->getSemanticId(), 7); // object-specific attributes @@ -1869,8 +1869,8 @@ void AttributesConfigsTest::testArticulatedObjectAttrVals( const std::string& assetPath, const std::string& urdfPath) { // match values set in test JSON - CORRADE_COMPARE(artObjAttr->getURDFPath(), urdfPath); - CORRADE_COMPARE(artObjAttr->getRenderAssetHandle(), assetPath); + CORRADE_COMPARE(artObjAttr->getURDFFullPath(), urdfPath); + CORRADE_COMPARE(artObjAttr->getRenderAssetFullPath(), assetPath); CORRADE_COMPARE(artObjAttr->getSemanticId(), 100); CORRADE_COMPARE(static_cast(artObjAttr->getBaseType()), diff --git a/src/tests/MetadataMediatorTest.cpp b/src/tests/MetadataMediatorTest.cpp index 07d743db3e..b78e52f649 100644 --- a/src/tests/MetadataMediatorTest.cpp +++ b/src/tests/MetadataMediatorTest.cpp @@ -113,7 +113,7 @@ void MetadataMediatorTest::testDataset0() { // verify that all attributes' names are the same as the render handles // (which were the original files) CORRADE_COMPARE(glbStageAttr->getHandle(), - glbStageAttr->getRenderAssetHandle()); + glbStageAttr->getRenderAssetFullPath()); } // get list of matching handles for base - should always only be 1 @@ -124,7 +124,7 @@ void MetadataMediatorTest::testDataset0() { auto stageAttr = stageAttributesMgr->getObjectCopyByHandle(stageAttrHandles[0]); // get render asset handle for later comparison - auto renderAssetHandle = stageAttr->getRenderAssetHandle(); + auto renderAssetHandle = stageAttr->getRenderAssetFullPath(); // verify existence CORRADE_VERIFY(stageAttr); // verify set to values in file @@ -161,7 +161,7 @@ void MetadataMediatorTest::testDataset0() { // verify existence CORRADE_VERIFY(stageAttr); // verify set to values in dataset_config file - auto newRenderAssetHandle = stageAttr->getRenderAssetHandle(); + auto newRenderAssetHandle = stageAttr->getRenderAssetFullPath(); // verify same renderasset handle to loaded stage attributes CORRADE_COMPARE(renderAssetHandle, newRenderAssetHandle); // verify values set correctly @@ -246,7 +246,7 @@ void MetadataMediatorTest::testDataset0() { // verify existence CORRADE_VERIFY(objAttr); // verify set to values in dataset_config file - newRenderAssetHandle = objAttr->getRenderAssetHandle(); + newRenderAssetHandle = objAttr->getRenderAssetFullPath(); // verify same renderasset handle to loaded stage attributes CORRADE_VERIFY(newRenderAssetHandle.find("dataset_test_object3.glb") != std::string::npos); @@ -445,12 +445,12 @@ void MetadataMediatorTest::testDataset0() { const auto semanticAttr1 = semanticMgr->getObjectCopyByHandle("semantic_descriptor_path1"); - CORRADE_COMPARE(semanticAttr1->getSemanticDescriptorFilename(), + CORRADE_COMPARE(semanticAttr1->getSemanticDescriptorFullPath(), "test_semantic_descriptor_path1"); const auto semanticAttr2 = semanticMgr->getObjectCopyByHandle("semantic_descriptor_path2"); - CORRADE_COMPARE(semanticAttr2->getSemanticDescriptorFilename(), + CORRADE_COMPARE(semanticAttr2->getSemanticDescriptorFullPath(), "test_semantic_descriptor_path2"); // end test LoadSemanticScene diff --git a/src/tests/SimTest.cpp b/src/tests/SimTest.cpp index 5fba4cd22e..ab394bbbfe 100644 --- a/src/tests/SimTest.cpp +++ b/src/tests/SimTest.cpp @@ -586,7 +586,7 @@ void SimTest::loadingObjectTemplates() { CORRADE_COMPARE(templateIndex2, templateIndex); ObjectAttributes::ptr newTemplate2 = objectAttribsMgr->getObjectCopyByHandle(boxPath); - CORRADE_COMPARE(newTemplate2->getRenderAssetHandle(), chairPath); + CORRADE_COMPARE(newTemplate2->getRenderAssetFullPath(), chairPath); } void SimTest::buildingPrimAssetObjectTemplates() { From 9f19cdb861c622bc9db51b08f63a170131d69f60 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Thu, 16 May 2024 15:20:32 -0400 Subject: [PATCH 03/14] --Put path-finalization in separate function. This will obviate the need for registering a template before it can be used. Mainly going to be consumed by tests, which often bypass internal control-flow branches that would otherwise automatically register these modified templates. --- .../metadata/managers/AOAttributesManager.cpp | 65 ++++--- .../metadata/managers/AOAttributesManager.h | 11 ++ .../managers/AssetAttributesManager.h | 11 ++ .../metadata/managers/AttributesManagerBase.h | 160 +++++++++++----- .../managers/LightLayoutAttributesManager.h | 11 ++ .../managers/ObjectAttributesManager.cpp | 113 ++++++----- .../managers/ObjectAttributesManager.h | 10 + .../managers/PbrShaderAttributesManager.h | 14 ++ .../managers/PhysicsAttributesManager.h | 11 ++ .../managers/SceneDatasetAttributesManager.h | 11 ++ .../managers/SceneInstanceAttributesManager.h | 11 ++ .../managers/SemanticAttributesManager.cpp | 47 +++-- .../managers/SemanticAttributesManager.h | 10 + .../managers/StageAttributesManager.cpp | 177 +++++++++--------- .../managers/StageAttributesManager.h | 10 + 15 files changed, 438 insertions(+), 234 deletions(-) diff --git a/src/esp/metadata/managers/AOAttributesManager.cpp b/src/esp/metadata/managers/AOAttributesManager.cpp index fa61cefd63..b6facf5c6c 100644 --- a/src/esp/metadata/managers/AOAttributesManager.cpp +++ b/src/esp/metadata/managers/AOAttributesManager.cpp @@ -193,30 +193,22 @@ AOAttributesManager::preRegisterObjectFinalize( << "` does not specify a valid URDF Filepath, so registration is " "aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; - } else if (!Cr::Utility::Path::exists(urdfFilePath)) { + } else if (!Cr::Utility::Path::exists(urdfFilePath) && + !Cr::Utility::Path::exists(urdfFullFilePath)) { // URDF File not found is bad ESP_ERROR(Mn::Debug::Flag::NoSpace) << "ArticulatedObjectAttributes template named `" << AOAttributesHandle - << "` specifies the URDF Filepath `" << urdfFilePath + << "` specifies the URDF Filepath `" << urdfFilePath << "` full path `" + << urdfFullFilePath << "`, but this file cannot be found, so registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } - // URDF file this articulated object attributes references - this->filterAttribsFilenames( - AOAttributesTemplate, urdfFilePath, urdfFullFilePath, - [AOAttributesTemplate](const std::string& urdfAsset) { - AOAttributesTemplate->setURDFPath(urdfAsset); - }, - [AOAttributesTemplate](const std::string& urdfAsset) { - AOAttributesTemplate->setURDFFullPath(urdfAsset); - }); // Furthermore, if 'skin' is specified as render_mode and no skin is // specified or the specified skin cannot be found, the registration should // also fail and the template should not be registered. bool useSkinRenderMode = AOAttributesTemplate->getRenderMode() == attributes::ArticulatedObjectRenderMode::Skin; - std::string dispStr(""); if (useSkinRenderMode) { // if 'skin' render mode is specified as render mode const std::string renderAssetHandle = @@ -231,7 +223,7 @@ AOAttributesManager::preRegisterObjectFinalize( Corrade::Utility::Path::split(urdfFilePath).second()) .first()) .first(); - if (renderAssetHandle.empty()) { + if (renderAssetHandle.empty() && renderAssetFullPath.empty()) { // Empty is bad when 'skin' render mode is specified ESP_ERROR(Mn::Debug::Flag::NoSpace) << "ArticulatedObjectAttributes template named `" @@ -241,10 +233,8 @@ AOAttributesManager::preRegisterObjectFinalize( << "`, but no render asset was specifed in the configuration, so " "registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; - } else if (!Cr::Utility::Path::exists(renderAssetHandle)) { - // Otherwise, if renderAssetFullPath exists, this attributes is copy of an - // existing already-processed attributes with values set - + } else if (!Cr::Utility::Path::exists(renderAssetHandle) && + !Cr::Utility::Path::exists(renderAssetFullPath)) { // Skin render asset specified not found is bad when 'skin' render mode // is specified ESP_ERROR(Mn::Debug::Flag::NoSpace) @@ -252,31 +242,48 @@ AOAttributesManager::preRegisterObjectFinalize( << AOAttributesHandle << "` specifies a render mode of `skin` for the AO created by `" << urdfSimpleName << "`, but the render asset specified, `" - << renderAssetHandle + << renderAssetHandle << "` full path `" << renderAssetFullPath << "` cannot be found, so registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } + } + // filter all paths properly so that the handles don't have filepaths and the + // accessors are hidden fields + this->finalizeAttrPathsBeforeRegister(AOAttributesTemplate); + + return core::managedContainers::ManagedObjectPreregistration::Success; +} // AOAttributesManager::preRegisterObjectFinalize + +void AOAttributesManager::finalizeAttrPathsBeforeRegister( + const attributes::ArticulatedObjectAttributes::ptr& AOAttributesTemplate) + const { + // URDF file this articulated object attributes references + this->filterAttribsFilenames( + AOAttributesTemplate, AOAttributesTemplate->getURDFPath(), + AOAttributesTemplate->getURDFFullPath(), + [AOAttributesTemplate](const std::string& urdfAsset) { + AOAttributesTemplate->setURDFPath(urdfAsset); + }, + [AOAttributesTemplate](const std::string& urdfAsset) { + AOAttributesTemplate->setURDFFullPath(urdfAsset); + }); + bool useSkinRenderMode = AOAttributesTemplate->getRenderMode() == + attributes::ArticulatedObjectRenderMode::Skin; + if (useSkinRenderMode) { // Render asset filename filter out path and set internal reference to - // full filepaath + // full filepath this->filterAttribsFilenames( - AOAttributesTemplate, renderAssetHandle, renderAssetFullPath, + AOAttributesTemplate, AOAttributesTemplate->getRenderAssetHandle(), + AOAttributesTemplate->getRenderAssetFullPath(), [AOAttributesTemplate](const std::string& renderAsset) { AOAttributesTemplate->setRenderAssetHandle(renderAsset); }, [AOAttributesTemplate](const std::string& renderAsset) { AOAttributesTemplate->setRenderAssetFullPath(renderAsset); }); - - dispStr = Cr::Utility::formatString(" and render asset file path `{}`", - renderAssetHandle); } - ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "AO : `" << AOAttributesHandle << "` has urdf filename `" - << urdfFilePath << "`" << dispStr << "| file dir `" - << AOAttributesTemplate->getFileDirectory() << "`"; - return core::managedContainers::ManagedObjectPreregistration::Success; -} // AOAttributesManager::preRegisterObjectFinalize +} // AOAttributesManager::finalizeAttrPathsBeforeRegister std::map AOAttributesManager::getArticulatedObjectModelFilenames() const { diff --git a/src/esp/metadata/managers/AOAttributesManager.h b/src/esp/metadata/managers/AOAttributesManager.h index 0325890ca1..d9dee7a4ab 100644 --- a/src/esp/metadata/managers/AOAttributesManager.h +++ b/src/esp/metadata/managers/AOAttributesManager.h @@ -73,6 +73,17 @@ class AOAttributesManager */ std::map getArticulatedObjectModelFilenames() const; + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::ArticulatedObjectAttributes::ptr& attributes) + const override; + protected: /** * @brief Parse Marker_sets object in json, if present. diff --git a/src/esp/metadata/managers/AssetAttributesManager.h b/src/esp/metadata/managers/AssetAttributesManager.h index 02a6e4c114..705c861e6e 100644 --- a/src/esp/metadata/managers/AssetAttributesManager.h +++ b/src/esp/metadata/managers/AssetAttributesManager.h @@ -126,6 +126,17 @@ class AssetAttributesManager const std::string& filename, const io::JsonGenericValue& jsonConfig) override; + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + CORRADE_UNUSED const attributes::AbstractPrimitiveAttributes::ptr& + attributes) const override {} + /** * @brief Method to take an existing attributes and set its values from passed * json config file. diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index 794146efb7..d0877f4ec0 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -236,6 +236,16 @@ class AttributesManager : public ManagedFileBasedContainer { return ""; } // getFullAttrNameFromStr + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + virtual void finalizeAttrPathsBeforeRegister( + const AttribsPtr& attributes) const = 0; + protected: /** * @brief Called internally right before attribute registration. Filepaths @@ -245,11 +255,13 @@ class AttributesManager : public ManagedFileBasedContainer { * can be easily found and consumed on command. However, saving fully * qualified filepaths to JSON configs is undesirable. * - * This function will query the passed @p attributes for a string using the - * @p relPathGetter to acquire the fully-qualified filename. It will set that - * value to be hidden in the attributes using @p fqPathSetter and then it will - * strip the attributes' filepath, if it is present, and set it as the - * relative value at @p relPathSetter . + * This function will examine the @p curRelPathName to see that it is a + * relative path in relation to the @p attributes' set filepath, and if not it + * will strip out the path information and resave the name to @p rePathSetter. + * It will query the passed @p curFQPathName to see that it is a fully + * qualified path to a file that exists, and if not it will add the + * attributes' filepath and resave it to @p fqPathSetter. + * * * It is assumed that what is passed to this function always referneces a * filepath, so if, for example, this is called on a render asseet filepath, @@ -258,48 +270,19 @@ class AttributesManager : public ManagedFileBasedContainer { * * @param attributes The Configuration-backed attributes owning the filepath * in question. - * @param relPathGetter The relative filepath getter in the attributes + * @param curRelPathName The currently set relative path filepath in the + * attributes + * @param curFQPathName The currently set fully qualified filepath in the + * attributes * @param relPathSetter The relative filepath setter in the attributes - * @param fqPathSetter The string tag for the filepath we want to be fully - * qualified. + * @param fqPathSetter The fully qualified filepath setter in the attributes */ void filterAttribsFilenames( - const attributes::AbstractAttributes::ptr& attributes, - const std::function& relPathGetter, + const AttribsPtr& attributes, + const std::string& curRelPathName, + const std::string& curFQPathName, const std::function& relPathSetter, - const std::function& fqPathSetter) const { - // Get the attributes filepath that our desired filepath should be relative - // to - std::string attrFilepath = attributes->getFileDirectory(); - // verify attributes filepath exists - if (CrPath::isDirectory(attrFilepath)) { - auto len = attrFilepath.length(); - // Get the filepath - std::string fqFilepath = relPathGetter(); - if (CrPath::exists(fqFilepath)) { - // Make sure attrFilepath is not longer than the filepath in - // question - if (len < fqFilepath.length()) { - if (fqFilepath.find(attrFilepath) != std::string::npos) { - // Set the fully qualified value - fqPathSetter(fqFilepath); - - ESP_ERROR() << "AttrHandle :" << attributes->getHandle() - << "|Getter result : " << fqFilepath - << " filepath :" << attrFilepath; - - auto relFilepath = std::string(fqFilepath); - // assume the undesired portion of the filepath always is at the - // beginning, adding 1 for the path separator - relFilepath.erase(0, len + 1); - // - relPathSetter(relFilepath); - } // if currently set relative handle contains filepath - } // if attributes dir is correct length - } // if relative filepath actually exists/is findable (i.e.is fully - // qualified) - } // if attributes dir is set properly - } // filterAttribsFilenames + const std::function& fqPathSetter) const; /** * @brief Called intenrally from createObject. This will create either a @@ -310,7 +293,7 @@ class AttributesManager : public ManagedFileBasedContainer { * @param filename the file holding the configuration of the object * @param msg reference to progress message * @param registerObj whether the new object should be registered in library - * @return the create @ref esp::metadata::attributes::AbstractAttributes. + * @return the created @ref esp::metadata::attributes::AbstractAttributes. */ AttribsPtr createFromJsonOrDefaultInternal(const std::string& filename, std::string& msg, @@ -378,7 +361,7 @@ class AttributesManager : public ManagedFileBasedContainer { * asset filename exists or not. */ bool setFilenameFromDefaultTag( - const attributes::AbstractAttributes::ptr& attributes, + const AttribsPtr& attributes, const std::string& srcAssetFilename, const std::function& filenameSetter); @@ -407,7 +390,7 @@ class AttributesManager : public ManagedFileBasedContainer { * specification. */ bool setAttributesHandleFromDefaultTag( - const attributes::AbstractAttributes::ptr& attributes, + const AttribsPtr& attributes, const std::string& srcAssetHandle, const std::function& handleSetter); @@ -638,7 +621,7 @@ bool AttributesManager::parseSubconfigJsonVals( template bool AttributesManager::setFilenameFromDefaultTag( - const attributes::AbstractAttributes::ptr& attributes, + const AttribsPtr& attributes, const std::string& srcAssetFilename, const std::function& filenameSetter) { if (srcAssetFilename.empty()) { @@ -692,7 +675,7 @@ bool AttributesManager::setFilenameFromDefaultTag( template bool AttributesManager::setAttributesHandleFromDefaultTag( - const attributes::AbstractAttributes::ptr& attributes, + const AttribsPtr& attributes, const std::string& srcAssetHandle, const std::function& handleSetter) { if (srcAssetHandle.empty()) { @@ -717,6 +700,87 @@ bool AttributesManager::setAttributesHandleFromDefaultTag( return false; } // AttributesManager::setAttributesHandleFromDefaultTag +template +void AttributesManager::filterAttribsFilenames( + const AttribsPtr& attributes, + const std::string& curRelPathName, + const std::string& curFQPathName, + const std::function& relPathSetter, + const std::function& fqPathSetter) const { + const std::string curFullyQualifiedPathName = + (curFQPathName.empty() ? curRelPathName : curFQPathName); + const std::string curRelativePathName = + (curRelPathName.empty() ? curFQPathName : curRelPathName); + + std::string dispString = Cr::Utility::formatString( + "AttrHandle `{}` class :`{}`|curRelPathName `{}`|curFQPathName " + ":`{}`|nonEmptyRel " + "`{}`|nonEmptyFQ :`{}`", + attributes->getHandle(), attributes->getClassKey(), curRelPathName, + curFQPathName, curRelativePathName, curFullyQualifiedPathName); + + if (curRelativePathName.empty() && curFullyQualifiedPathName.empty()) { + ESP_ERROR() << "BOTH RELATIVE AND FQ PATHS ARE EMPTY Skipping: " + << dispString << "\n"; + } + + // Initialize potentially empty fields + relPathSetter(curRelativePathName); + fqPathSetter(curFullyQualifiedPathName); + + // Get the attributes filepath that our desired filepath should be + // relative to + const std::string attrFilepath = attributes->getFileDirectory(); + if (attrFilepath.empty()) { + ESP_ERROR() << "EMPTY FILEPATH Skipping : " << dispString << "\n"; + // if filepath is empty, do nothing. + return; + } + + // verify attributes filepath exists + if (CrPath::isDirectory(attrFilepath)) { + Cr::Utility::formatInto(dispString, dispString.size(), + "|attr Filepath `{}`", attrFilepath); + + auto len = attrFilepath.length(); + // Check if expected relative filepath is accessible on disk (therefore is + // fully qualified) + if (CrPath::exists(curRelativePathName)) { + // Set the fully qualified value to be the found curRelPathName + fqPathSetter(curRelativePathName); + // Get new path relative to attrFilepath + const std::string newRelFilepath = + io::getPathRealtiveToAbsPath(curRelativePathName, attrFilepath); + // save the new relative filepath + relPathSetter(newRelFilepath); + Cr::Utility::formatInto(dispString, dispString.size(), + "|curRelPathName is FOUND/FQ|newRelFP `{}`", + newRelFilepath); + } else if (curRelativePathName.empty()) { + Cr::Utility::formatInto(dispString, dispString.size(), + "|!!! curRelPathName is empty"); + } else { + // Current relative filepath cannot be found and is not empty, so assume + // it is already appropriately formatted + } + + if (CrPath::exists(curFullyQualifiedPathName)) { + // Current fully qualified pathname is found + Cr::Utility::formatInto(dispString, dispString.size(), + "|curFQPathName is FOUND/FQ"); + + // TODO : Populate relPathName with relative path pathname? + } + + } // if attributes dir is set properly + else { + Cr::Utility::formatInto(dispString, dispString.size(), + "|NON-EXISTING FILEPATH `{}` ", attrFilepath); + } + + ESP_ERROR() << "\n" << dispString << "\n"; +} // filterAttribsFilenames + template template void AttributesManager::setEnumStringFromJsonDoc( diff --git a/src/esp/metadata/managers/LightLayoutAttributesManager.h b/src/esp/metadata/managers/LightLayoutAttributesManager.h index 06e9fa0d36..9cb4b78a06 100644 --- a/src/esp/metadata/managers/LightLayoutAttributesManager.h +++ b/src/esp/metadata/managers/LightLayoutAttributesManager.h @@ -80,6 +80,17 @@ class LightLayoutAttributesManager gfx::LightSetup createLightSetupFromAttributes( const std::string& lightConfigName); + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + CORRADE_UNUSED const attributes::LightLayoutAttributes::ptr& attributes) + const override {} + protected: /** * @brief Used Internally. Create and configure newly-created attributes diff --git a/src/esp/metadata/managers/ObjectAttributesManager.cpp b/src/esp/metadata/managers/ObjectAttributesManager.cpp index 84eeaefc71..dbdeb955ef 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.cpp +++ b/src/esp/metadata/managers/ObjectAttributesManager.cpp @@ -221,12 +221,10 @@ ObjectAttributesManager::preRegisterObjectFinalize( return core::managedContainers::ManagedObjectPreregistration::Failed; } - // Handles for rendering and collision assets - std::string renderAssetHandle = objectTemplate->getRenderAssetHandle(); - std::string renderAssetFullPath = objectTemplate->getRenderAssetFullPath(); - std::string collisionAssetHandle = objectTemplate->getCollisionAssetHandle(); - std::string collisionAssetFullPath = - objectTemplate->getCollisionAssetFullPath(); + // Handles for rendering assets + const std::string renderAssetHandle = objectTemplate->getRenderAssetHandle(); + const std::string renderAssetFullPath = + objectTemplate->getRenderAssetFullPath(); // Clear map to add to ptr from previous registration mapToAddTo_ = nullptr; @@ -238,33 +236,13 @@ ObjectAttributesManager::preRegisterObjectFinalize( objectTemplate->setRenderAssetIsPrimitive(true); objectTemplate->setRenderAssetFullPath(renderAssetHandle); mapToAddTo_ = &physicsSynthObjTmpltLibByID_; - } else if (Cr::Utility::Path::exists(renderAssetHandle)) { + } else if (Cr::Utility::Path::exists(renderAssetHandle) || + Cr::Utility::Path::exists(renderAssetFullPath)) { // Check if renderAssetHandle is valid file name and is found in file system // - if so then setRenderAssetIsPrimitive to false and set map of IDs->Names // to physicsFileObjTmpltLibByID_ - verify file exists objectTemplate->setRenderAssetIsPrimitive(false); mapToAddTo_ = &physicsFileObjTmpltLibByID_; - // Render asset filename filter out path and set internal reference to full - // filepaath - this->filterAttribsFilenames( - objectTemplate, - [objectTemplate](void) -> std::string { - return objectTemplate->getRenderAssetHandle(); - }, - [objectTemplate](const std::string& renderAsset) { - objectTemplate->setRenderAssetHandle(renderAsset); - }, - [objectTemplate](const std::string& renderAsset) { - objectTemplate->setRenderAssetFullPath(renderAsset); - }); - // Re-set to catch path removal. - renderAssetHandle = objectTemplate->getRenderAssetHandle(); - - } else if (Cr::Utility::Path::exists(renderAssetFullPath)) { - // not prim and does not exist on disk, perhaps the fully qualified version - // of the handle was set already and exists, which means we don't need to do - // anything else. - objectTemplate->setRenderAssetIsPrimitive(false); } else if (forceRegistration) { // Forcing registration in case of computationaly generated assets ESP_WARNING(Mn::Debug::Flag::NoSpace) @@ -286,36 +264,22 @@ ObjectAttributesManager::preRegisterObjectFinalize( "asset, so registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } + // Handles for collision assets + const std::string collisionAssetHandle = + objectTemplate->getCollisionAssetHandle(); + const std::string collisionAssetFullPath = + objectTemplate->getCollisionAssetFullPath(); if (this->isValidPrimitiveAttributes(collisionAssetHandle)) { // If collisionAssetHandle corresponds to valid/existing primitive // attributes then setCollisionAssetIsPrimitive to true objectTemplate->setCollisionAssetIsPrimitive(true); objectTemplate->setCollisionAssetFullPath(collisionAssetHandle); - } else if (Cr::Utility::Path::exists(collisionAssetHandle)) { + } else if (Cr::Utility::Path::exists(collisionAssetHandle) || + Cr::Utility::Path::exists(collisionAssetFullPath)) { // Check if collisionAssetHandle is valid file name and is found in file // system - if so then setCollisionAssetIsPrimitive to false objectTemplate->setCollisionAssetIsPrimitive(false); - - // Collision asset filename filter out path and set internal reference to - // full filepaath - this->filterAttribsFilenames( - objectTemplate, - [objectTemplate](void) -> std::string { - return objectTemplate->getCollisionAssetHandle(); - }, - [objectTemplate](const std::string& colHndl) { - objectTemplate->setCollisionAssetHandle(colHndl); - }, - [objectTemplate](const std::string& colHndl) { - objectTemplate->setCollisionAssetFullPath(colHndl); - }); - - } else if (Cr::Utility::Path::exists(collisionAssetFullPath)) { - // not prim and does not exist on disk, perhaps the fully qualified version - // of the handle was set already and exists, which means we don't need to do - // anything else. - objectTemplate->setCollisionAssetIsPrimitive(false); } else { // Else, means no collision data specified, use specified render data ESP_DEBUG(Mn::Debug::Flag::NoSpace) @@ -326,25 +290,60 @@ ObjectAttributesManager::preRegisterObjectFinalize( << renderAssetHandle << "."; // Set values to match render asset values - objectTemplate->setCollisionAssetHandle(renderAssetHandle); + objectTemplate->setCollisionAssetHandle( + objectTemplate->getRenderAssetHandle()); objectTemplate->setCollisionAssetFullPath( objectTemplate->getRenderAssetFullPath()); - objectTemplate->setCollisionAssetIsPrimitive( objectTemplate->getRenderAssetIsPrimitive()); } + // filter all paths properly so that the handles don't have filepaths and the + // accessors are hidden fields + if (!objectTemplate->getRenderAssetIsPrimitive()) { + this->finalizeAttrPathsBeforeRegister(objectTemplate); + } + // Clear dirty flag from when asset handles are changed + objectTemplate->setIsClean(); + return core::managedContainers::ManagedObjectPreregistration::Success; +} // ObjectAttributesManager::preRegisterObjectFinalize + +void ObjectAttributesManager::finalizeAttrPathsBeforeRegister( + const attributes::ObjectAttributes::ptr& objectTemplate) const { // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "Obj `" << objectTemplateHandle << "`: Render fn `" + // << "BEFORE Obj `" << objectTemplateHandle << "`: Render fn `" // << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" // << objectTemplate->getCollisionAssetHandle() << "`| file dir `" // << objectTemplate->getFileDirectory() << "`"; + // Render asset filename filter out path and set internal reference to full + // filepaath + this->filterAttribsFilenames( + objectTemplate, objectTemplate->getRenderAssetHandle(), + objectTemplate->getRenderAssetFullPath(), + [objectTemplate](const std::string& renderAsset) { + objectTemplate->setRenderAssetHandle(renderAsset); + }, + [objectTemplate](const std::string& renderAsset) { + objectTemplate->setRenderAssetFullPath(renderAsset); + }); + // Collision asset filename filter out path and set internal reference to + // full filepaath + this->filterAttribsFilenames( + objectTemplate, objectTemplate->getCollisionAssetHandle(), + objectTemplate->getCollisionAssetFullPath(), + [objectTemplate](const std::string& colHndl) { + objectTemplate->setCollisionAssetHandle(colHndl); + }, + [objectTemplate](const std::string& colHndl) { + objectTemplate->setCollisionAssetFullPath(colHndl); + }); - // Clear dirty flag from when asset handles are changed - objectTemplate->setIsClean(); - - return core::managedContainers::ManagedObjectPreregistration::Success; -} // ObjectAttributesManager::preRegisterObjectFinalize + // ESP_ERROR(Mn::Debug::Flag::NoSpace) + // << "AFTER Obj `" << objectTemplateHandle << "`: Render fn `" + // << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" + // << objectTemplate->getCollisionAssetHandle() << "`| file dir `" + // << objectTemplate->getFileDirectory() << "`"; +} void ObjectAttributesManager::postRegisterObjectHandling( int objectTemplateID, diff --git a/src/esp/metadata/managers/ObjectAttributesManager.h b/src/esp/metadata/managers/ObjectAttributesManager.h index 71a627cbcd..01525c8391 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.h +++ b/src/esp/metadata/managers/ObjectAttributesManager.h @@ -225,6 +225,16 @@ class ObjectAttributesManager const std::string& attributesTemplateHandle, bool forceRegistration) override; + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::ObjectAttributes::ptr& attributes) const override; + /** * @brief This method will perform any final manager-related handling after * successfully registering an object. diff --git a/src/esp/metadata/managers/PbrShaderAttributesManager.h b/src/esp/metadata/managers/PbrShaderAttributesManager.h index 1b645030cf..6e8b813fbb 100644 --- a/src/esp/metadata/managers/PbrShaderAttributesManager.h +++ b/src/esp/metadata/managers/PbrShaderAttributesManager.h @@ -95,6 +95,20 @@ class PbrShaderAttributesManager } } // PbrShaderAttributesManager::setAllDirectLightsEnabled + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * + * TODO : If/When we begin treating IBL filepaths like we do other paths, this + * will need to be implemented. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + CORRADE_UNUSED const attributes::PbrShaderAttributes::ptr& attributes) + const override{}; + protected: /** * @brief Used Internally. Create and configure newly-created attributes with diff --git a/src/esp/metadata/managers/PhysicsAttributesManager.h b/src/esp/metadata/managers/PhysicsAttributesManager.h index 18f8e1898b..e7ae10732a 100644 --- a/src/esp/metadata/managers/PhysicsAttributesManager.h +++ b/src/esp/metadata/managers/PhysicsAttributesManager.h @@ -63,6 +63,17 @@ class PhysicsAttributesManager void setValsFromJSONDoc(attributes::PhysicsManagerAttributes::ptr attribs, const io::JsonGenericValue& jsonConfig) override; + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + CORRADE_UNUSED const attributes::PhysicsManagerAttributes::ptr& + attributes) const override {} + protected: /** * @brief Used Internally. Create and configure newly-created attributes with diff --git a/src/esp/metadata/managers/SceneDatasetAttributesManager.h b/src/esp/metadata/managers/SceneDatasetAttributesManager.h index 87f6d5fcdb..7b2b27ea09 100644 --- a/src/esp/metadata/managers/SceneDatasetAttributesManager.h +++ b/src/esp/metadata/managers/SceneDatasetAttributesManager.h @@ -93,6 +93,17 @@ class SceneDatasetAttributesManager } } // SceneDatasetAttributesManager::setDefaultPbrShaderAttributesHandle + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::SceneDatasetAttributes::ptr& attributes) + const override {} + protected: /** * @brief This will validate a loaded dataset map with file location values diff --git a/src/esp/metadata/managers/SceneInstanceAttributesManager.h b/src/esp/metadata/managers/SceneInstanceAttributesManager.h index 26e4b35698..8f9c6246d3 100644 --- a/src/esp/metadata/managers/SceneInstanceAttributesManager.h +++ b/src/esp/metadata/managers/SceneInstanceAttributesManager.h @@ -100,6 +100,17 @@ class SceneInstanceAttributesManager return attributes::SceneAOInstanceAttributes::create(handle); } + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + CORRADE_UNUSED const attributes::SceneInstanceAttributes::ptr& attributes) + const override {} + protected: /** * @brief Gets the name/key value of the appropriate enum corresponding to the diff --git a/src/esp/metadata/managers/SemanticAttributesManager.cpp b/src/esp/metadata/managers/SemanticAttributesManager.cpp index 57da1f7628..c602948a9a 100644 --- a/src/esp/metadata/managers/SemanticAttributesManager.cpp +++ b/src/esp/metadata/managers/SemanticAttributesManager.cpp @@ -223,13 +223,28 @@ SemanticAttributesManager::preRegisterObjectFinalize( attributes::SemanticAttributes::ptr semanticAttributes, const std::string& semanticAttrHandle, CORRADE_UNUSED bool forceRegistration) { + // filter all paths properly so that the handles don't have filepaths and the + // accessors are hidden fields + this->finalizeAttrPathsBeforeRegister(semanticAttributes); + + return core::managedContainers::ManagedObjectPreregistration::Success; +} // SemanticAttributesManager::preRegisterObjectFinalize + +void SemanticAttributesManager::finalizeAttrPathsBeforeRegister( + const attributes::SemanticAttributes::ptr& semanticAttributes) const { // filter filepaths of full path qualifiers + // ESP_ERROR(Mn::Debug::Flag::NoSpace) + // << "BEFORE : Semantic Attr `" << semanticAttrHandle + // << "`| semantic asset fn `" + // << semanticAttributes->getSemanticAssetHandle() + // << "`| semantic descriptor fn `" + // << semanticAttributes->getSemanticDescriptorFilename() + // << "`| file dir `" + // << semanticAttributes->getFileDirectory() << "`"; // Semantic asset filename this->filterAttribsFilenames( - semanticAttributes, - [semanticAttributes](void) -> std::string { - return semanticAttributes->getSemanticAssetHandle(); - }, + semanticAttributes, semanticAttributes->getSemanticAssetHandle(), + semanticAttributes->getSemanticAssetFullPath(), [semanticAttributes](const std::string& semanticAsset) { semanticAttributes->setSemanticAssetHandle(semanticAsset); }, @@ -238,10 +253,8 @@ SemanticAttributesManager::preRegisterObjectFinalize( }); // Semantic descriptor filename this->filterAttribsFilenames( - semanticAttributes, - [semanticAttributes](void) -> std::string { - return semanticAttributes->getSemanticDescriptorFilename(); - }, + semanticAttributes, semanticAttributes->getSemanticDescriptorFilename(), + semanticAttributes->getSemanticDescriptorFullPath(), [semanticAttributes](const std::string& semanticAsset) { semanticAttributes->setSemanticDescriptorFilename(semanticAsset); }, @@ -249,15 +262,17 @@ SemanticAttributesManager::preRegisterObjectFinalize( semanticAttributes->setSemanticDescriptorFullPath(semanticAsset); }); - ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "Semantic Attr `" << semanticAttrHandle << "`| semantic asset fn `" - << semanticAttributes->getSemanticAssetHandle() - << "`| semantic descriptor fn `" - << semanticAttributes->getSemanticDescriptorFilename() << "`| file dir `" - << semanticAttributes->getFileDirectory() << "`"; + // ESP_ERROR(Mn::Debug::Flag::NoSpace) + // << "AFTER : Semantic Attr `" << semanticAttrHandle + // << "`| semantic asset fn `" + // << semanticAttributes->getSemanticAssetHandle() + // << "`| semantic descriptor fn `" + // << semanticAttributes->getSemanticDescriptorFilename() + // << "`| file dir `" + // << semanticAttributes->getFileDirectory() << "`"; // No pre-registration conditioning performed - return core::managedContainers::ManagedObjectPreregistration::Success; -} + +} // SemanticAttributesManager::finalizeAttrPathsBeforeRegister } // namespace managers } // namespace metadata diff --git a/src/esp/metadata/managers/SemanticAttributesManager.h b/src/esp/metadata/managers/SemanticAttributesManager.h index c4fe73c4ec..c9937c0c5c 100644 --- a/src/esp/metadata/managers/SemanticAttributesManager.h +++ b/src/esp/metadata/managers/SemanticAttributesManager.h @@ -70,6 +70,16 @@ class SemanticAttributesManager return attributes::SemanticVolumeAttributes::create(handle); } + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::SemanticAttributes::ptr& attributes) const override; + protected: /** * @brief Used Internally. Create a @ref diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index 82320e3433..4d2f15701e 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -379,12 +379,10 @@ StageAttributesManager::preRegisterObjectFinalize( return core::managedContainers::ManagedObjectPreregistration::Failed; } - // Handles for rendering and collision assets - std::string renderAssetHandle = stageAttributes->getRenderAssetHandle(); - std::string renderAssetFullPath = stageAttributes->getRenderAssetFullPath(); - std::string collisionAssetHandle = stageAttributes->getCollisionAssetHandle(); - std::string collisionAssetFullPath = - stageAttributes->getCollisionAssetFullPath(); + // Handles for rendering assets + const std::string renderAssetHandle = stageAttributes->getRenderAssetHandle(); + const std::string renderAssetFullPath = + stageAttributes->getRenderAssetFullPath(); bool stageIsNone = stageAttributesHandle.find("NONE") != std::string::npos; // verify these represent legitimate assets if (this->isValidPrimitiveAttributes(renderAssetHandle)) { @@ -393,30 +391,10 @@ StageAttributesManager::preRegisterObjectFinalize( // physicsSynthObjTmpltLibByID_ stageAttributes->setRenderAssetIsPrimitive(true); stageAttributes->setRenderAssetFullPath(renderAssetHandle); - } else if (Cr::Utility::Path::exists(renderAssetHandle)) { + } else if (Cr::Utility::Path::exists(renderAssetHandle) || + Cr::Utility::Path::exists(renderAssetFullPath)) { // Check if renderAssetHandle is valid file name and is found in file - // system - if so then setRenderAssetIsPrimitive to false and set map of - // IDs->Names to physicsFileObjTmpltLibByID_ - verify file exists - stageAttributes->setRenderAssetIsPrimitive(false); - // Render asset filename filter out path and set internal reference to full - // filepaath - this->filterAttribsFilenames( - stageAttributes, - [stageAttributes](void) -> std::string { - return stageAttributes->getRenderAssetHandle(); - }, - [stageAttributes](const std::string& renderAsset) { - stageAttributes->setRenderAssetHandle(renderAsset); - }, - [stageAttributes](const std::string& renderAsset) { - stageAttributes->setRenderAssetFullPath(renderAsset); - }); - // Re-set to catch path removal. - renderAssetHandle = stageAttributes->getRenderAssetHandle(); - } else if (Cr::Utility::Path::exists(renderAssetFullPath)) { - // not prim and does not exist on disk, perhaps the fully qualified version - // of the handle was set already and exists, which means we don't need to do - // anything else. + // system - if so then setRenderAssetIsPrimitive to false stageAttributes->setRenderAssetIsPrimitive(false); } else if (stageIsNone) { // Render asset handle will be NONE as well - force type to be unknown @@ -440,34 +418,22 @@ StageAttributesManager::preRegisterObjectFinalize( return core::managedContainers::ManagedObjectPreregistration::Failed; } + // Handles for collision assets + const std::string collisionAssetHandle = + stageAttributes->getCollisionAssetHandle(); + const std::string collisionAssetFullPath = + stageAttributes->getCollisionAssetFullPath(); if (this->isValidPrimitiveAttributes(collisionAssetHandle)) { // If collisionAssetHandle corresponds to valid/existing primitive // attributes then setCollisionAssetIsPrimitive to true stageAttributes->setCollisionAssetIsPrimitive(true); stageAttributes->setCollisionAssetFullPath(collisionAssetHandle); - } else if (Cr::Utility::Path::exists(collisionAssetHandle)) { + } else if (Cr::Utility::Path::exists(collisionAssetHandle) || + (Cr::Utility::Path::exists(collisionAssetFullPath))) { // Check if collisionAssetHandle is valid file name and is found in file // system - if so then setCollisionAssetIsPrimitive to false stageAttributes->setCollisionAssetIsPrimitive(false); - // Collision asset filename filter out path and set internal reference to - // full filepaath - this->filterAttribsFilenames( - stageAttributes, - [stageAttributes](void) -> std::string { - return stageAttributes->getCollisionAssetHandle(); - }, - [stageAttributes](const std::string& colHndl) { - stageAttributes->setCollisionAssetHandle(colHndl); - }, - [stageAttributes](const std::string& colHndl) { - stageAttributes->setCollisionAssetFullPath(colHndl); - }); - } else if (Cr::Utility::Path::exists(collisionAssetFullPath)) { - // not prim and does not exist on disk, perhaps the fully qualified version - // of the handle was set already and exists, which means we don't need to do - // anything else. - stageAttributes->setCollisionAssetIsPrimitive(false); - } else if (std::string::npos != stageAttributesHandle.find("NONE")) { + } else if (stageIsNone) { // Collision asset handle will be NONE as well - force type to be unknown stageAttributes->setCollisionAssetType( getAssetTypeName(AssetType::Unknown)); @@ -482,29 +448,75 @@ StageAttributesManager::preRegisterObjectFinalize( "asset. Overriding with given render asset handle :" << renderAssetHandle << "."; - stageAttributes->setCollisionAssetHandle(renderAssetHandle); + stageAttributes->setCollisionAssetHandle( + stageAttributes->getCollisionAssetHandle()); + stageAttributes->setCollisionAssetFullPath( + stageAttributes->getCollisionAssetFullPath()); stageAttributes->setCollisionAssetIsPrimitive( stageAttributes->getRenderAssetIsPrimitive()); } + // filter all paths properly so that the handles don't have filepaths and the + // accessors are hidden fields + this->finalizeAttrPathsBeforeRegister(stageAttributes); + + stageAttributes->setIsClean(); + + return core::managedContainers::ManagedObjectPreregistration::Success; + +} // StageAttributesManager::preRegisterObjectFinalize + +void StageAttributesManager::finalizeAttrPathsBeforeRegister( + const attributes::StageAttributes::ptr& stageAttributes) const { + // ESP_ERROR(Mn::Debug::Flag::NoSpace) + // << "BEFORE : Stage `" << stageAttributesHandle << "`: Render rel `" + // << stageAttributes->getRenderAssetHandle() << "`: Render FQ `" + // << stageAttributes->getRenderAssetFullPath() << "`| Collision rel `" + // << stageAttributes->getCollisionAssetHandle() << "`| Collision FQ `" + // << stageAttributes->getCollisionAssetFullPath() << "`| navmesh rel `" + // << stageAttributes->getNavmeshAssetHandle() + // << "`| semantic asset rel `" + // << stageAttributes->getSemanticAssetHandle() + // << "`| semantic descriptor rel `" + // << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" + // << stageAttributes->getFileDirectory() << "`"; + + // Render asset filename filter out path and set internal reference to full + // filepath + this->filterAttribsFilenames( + stageAttributes, stageAttributes->getRenderAssetHandle(), + stageAttributes->getRenderAssetFullPath(), + [stageAttributes](const std::string& renderAsset) { + stageAttributes->setRenderAssetHandle(renderAsset); + }, + [stageAttributes](const std::string& renderAsset) { + stageAttributes->setRenderAssetFullPath(renderAsset); + }); + // Collision asset filename filter out path and set internal reference to + // full filepaath + this->filterAttribsFilenames( + stageAttributes, stageAttributes->getCollisionAssetHandle(), + stageAttributes->getCollisionAssetFullPath(), + [stageAttributes](const std::string& colHndl) { + stageAttributes->setCollisionAssetHandle(colHndl); + }, + [stageAttributes](const std::string& colHndl) { + stageAttributes->setCollisionAssetFullPath(colHndl); + }); // filter filepaths of full path qualifiers // Navmesh asset filename this->filterAttribsFilenames( - stageAttributes, - [stageAttributes](void) -> std::string { - return stageAttributes->getNavmeshAssetHandle(); + stageAttributes, stageAttributes->getNavmeshAssetHandle(), + stageAttributes->getNavmeshAssetFullPath(), + [stageAttributes](const std::string& navmeshAsset) { + stageAttributes->setNavmeshAssetHandle(navmeshAsset); }, - [stageAttributes](const std::string& semanticAsset) { - stageAttributes->setNavmeshAssetHandle(semanticAsset); - }, - [stageAttributes](const std::string& semanticAsset) { - stageAttributes->setNavmeshAssetFullPath(semanticAsset); + [stageAttributes](const std::string& navmeshAsset) { + stageAttributes->setNavmeshAssetFullPath(navmeshAsset); }); // Semantic asset filename this->filterAttribsFilenames( - stageAttributes, - [stageAttributes](void) -> std::string { - return stageAttributes->getSemanticAssetHandle(); - }, + stageAttributes, stageAttributes->getSemanticAssetHandle(), + stageAttributes->getSemanticAssetFullPath(), [stageAttributes](const std::string& semanticAsset) { stageAttributes->setSemanticAssetHandle(semanticAsset); }, @@ -513,33 +525,30 @@ StageAttributesManager::preRegisterObjectFinalize( }); // Semantic descriptor filename this->filterAttribsFilenames( - stageAttributes, - [stageAttributes](void) -> std::string { - return stageAttributes->getSemanticDescriptorFilename(); + stageAttributes, stageAttributes->getSemanticDescriptorFilename(), + stageAttributes->getSemanticDescriptorFullPath(), + [stageAttributes](const std::string& ssd) { + stageAttributes->setSemanticDescriptorFilename(ssd); }, - [stageAttributes](const std::string& semanticAsset) { - stageAttributes->setSemanticDescriptorFilename(semanticAsset); - }, - [stageAttributes](const std::string& semanticAsset) { - stageAttributes->setSemanticDescriptorFullPath(semanticAsset); + [stageAttributes](const std::string& ssd) { + stageAttributes->setSemanticDescriptorFullPath(ssd); }); - ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "Stage `" << stageAttributesHandle << "`: Render fn `" - << stageAttributes->getRenderAssetHandle() << "`| Collision fn `" - << stageAttributes->getCollisionAssetHandle() << "`| navmesh fn `" - << stageAttributes->getNavmeshAssetHandle() << "`| semantic asset fn `" - << stageAttributes->getSemanticAssetHandle() - << "`| semantic descriptor fn `" - << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" - << stageAttributes->getFileDirectory() << "`"; + // ESP_ERROR(Mn::Debug::Flag::NoSpace) + // << "AFTER : Stage `" << stageAttributesHandle << "`: Render rel `" + // << stageAttributes->getRenderAssetHandle() << "`: Render FQ `" + // << stageAttributes->getRenderAssetFullPath() << "`| Collision rel `" + // << stageAttributes->getCollisionAssetHandle() << "`| Collision FQ `" + // << stageAttributes->getCollisionAssetFullPath() << "`| navmesh rel `" + // << stageAttributes->getNavmeshAssetHandle() + // << "`| semantic asset rel `" + // << stageAttributes->getSemanticAssetHandle() + // << "`| semantic descriptor rel `" + // << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" + // << stageAttributes->getFileDirectory() << "`"; // Clear dirty flag from when asset handles are changed - stageAttributes->setIsClean(); - - return core::managedContainers::ManagedObjectPreregistration::Success; - -} // StageAttributesManager::registerAttributesTemplate +} } // namespace managers } // namespace metadata diff --git a/src/esp/metadata/managers/StageAttributesManager.h b/src/esp/metadata/managers/StageAttributesManager.h index 11171bbff4..5d48ffdd0b 100644 --- a/src/esp/metadata/managers/StageAttributesManager.h +++ b/src/esp/metadata/managers/StageAttributesManager.h @@ -153,6 +153,16 @@ class StageAttributesManager const std::string& StageAttributesHandle, bool forceRegistration) override; + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::StageAttributes::ptr& attributes) const override; + /** * @brief Not required for this manager. * From 3f20f12f6ce063f1b3c369b3dd011df533df5981 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Thu, 16 May 2024 16:28:12 -0400 Subject: [PATCH 04/14] --clang-tidy; missing return --- src/esp/metadata/managers/AttributesManagerBase.h | 9 +++++---- .../metadata/managers/ObjectAttributesManager.cpp | 4 +--- .../managers/SemanticAttributesManager.cpp | 15 +++++++-------- .../metadata/managers/StageAttributesManager.cpp | 4 +++- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index d0877f4ec0..a345d306fc 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -710,7 +710,7 @@ void AttributesManager::filterAttribsFilenames( const std::string curFullyQualifiedPathName = (curFQPathName.empty() ? curRelPathName : curFQPathName); const std::string curRelativePathName = - (curRelPathName.empty() ? curFQPathName : curRelPathName); + (curRelPathName.empty() ? curFullyQualifiedPathName : curRelPathName); std::string dispString = Cr::Utility::formatString( "AttrHandle `{}` class :`{}`|curRelPathName `{}`|curFQPathName " @@ -719,9 +719,11 @@ void AttributesManager::filterAttribsFilenames( attributes->getHandle(), attributes->getClassKey(), curRelPathName, curFQPathName, curRelativePathName, curFullyQualifiedPathName); + // If both relative and fully qualified paths are empty, if (curRelativePathName.empty() && curFullyQualifiedPathName.empty()) { ESP_ERROR() << "BOTH RELATIVE AND FQ PATHS ARE EMPTY Skipping: " - << dispString << "\n"; + << dispString; + return; } // Initialize potentially empty fields @@ -732,7 +734,7 @@ void AttributesManager::filterAttribsFilenames( // relative to const std::string attrFilepath = attributes->getFileDirectory(); if (attrFilepath.empty()) { - ESP_ERROR() << "EMPTY FILEPATH Skipping : " << dispString << "\n"; + ESP_ERROR() << "EMPTY FILEPATH Skipping : " << dispString; // if filepath is empty, do nothing. return; } @@ -742,7 +744,6 @@ void AttributesManager::filterAttribsFilenames( Cr::Utility::formatInto(dispString, dispString.size(), "|attr Filepath `{}`", attrFilepath); - auto len = attrFilepath.length(); // Check if expected relative filepath is accessible on disk (therefore is // fully qualified) if (CrPath::exists(curRelativePathName)) { diff --git a/src/esp/metadata/managers/ObjectAttributesManager.cpp b/src/esp/metadata/managers/ObjectAttributesManager.cpp index dbdeb955ef..c7a82fca1e 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.cpp +++ b/src/esp/metadata/managers/ObjectAttributesManager.cpp @@ -299,9 +299,7 @@ ObjectAttributesManager::preRegisterObjectFinalize( } // filter all paths properly so that the handles don't have filepaths and the // accessors are hidden fields - if (!objectTemplate->getRenderAssetIsPrimitive()) { - this->finalizeAttrPathsBeforeRegister(objectTemplate); - } + this->finalizeAttrPathsBeforeRegister(objectTemplate); // Clear dirty flag from when asset handles are changed objectTemplate->setIsClean(); diff --git a/src/esp/metadata/managers/SemanticAttributesManager.cpp b/src/esp/metadata/managers/SemanticAttributesManager.cpp index c602948a9a..68bcc54e53 100644 --- a/src/esp/metadata/managers/SemanticAttributesManager.cpp +++ b/src/esp/metadata/managers/SemanticAttributesManager.cpp @@ -221,7 +221,7 @@ void SemanticAttributesManager::setValsFromJSONDoc( core::managedContainers::ManagedObjectPreregistration SemanticAttributesManager::preRegisterObjectFinalize( attributes::SemanticAttributes::ptr semanticAttributes, - const std::string& semanticAttrHandle, + CORRADE_UNUSED const std::string& semanticAttrHandle, CORRADE_UNUSED bool forceRegistration) { // filter all paths properly so that the handles don't have filepaths and the // accessors are hidden fields @@ -234,13 +234,13 @@ void SemanticAttributesManager::finalizeAttrPathsBeforeRegister( const attributes::SemanticAttributes::ptr& semanticAttributes) const { // filter filepaths of full path qualifiers // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "BEFORE : Semantic Attr `" << semanticAttrHandle + // << "BEFORE : Semantic Attr `" << semanticAttributes->getHandle() // << "`| semantic asset fn `" // << semanticAttributes->getSemanticAssetHandle() // << "`| semantic descriptor fn `" // << semanticAttributes->getSemanticDescriptorFilename() - // << "`| file dir `" - // << semanticAttributes->getFileDirectory() << "`"; + // << "`| file directory `" << semanticAttributes->getFileDirectory() << + // "`"; // Semantic asset filename this->filterAttribsFilenames( semanticAttributes, semanticAttributes->getSemanticAssetHandle(), @@ -263,14 +263,13 @@ void SemanticAttributesManager::finalizeAttrPathsBeforeRegister( }); // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "AFTER : Semantic Attr `" << semanticAttrHandle + // << "AFTER : Semantic Attr `" << semanticAttributes->getHandle() // << "`| semantic asset fn `" // << semanticAttributes->getSemanticAssetHandle() // << "`| semantic descriptor fn `" // << semanticAttributes->getSemanticDescriptorFilename() - // << "`| file dir `" - // << semanticAttributes->getFileDirectory() << "`"; - // No pre-registration conditioning performed + // << "`| file directory `" << semanticAttributes->getFileDirectory() << + // "`"; } // SemanticAttributesManager::finalizeAttrPathsBeforeRegister diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index 4d2f15701e..4777a1fc7f 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -457,7 +457,9 @@ StageAttributesManager::preRegisterObjectFinalize( } // filter all paths properly so that the handles don't have filepaths and the // accessors are hidden fields - this->finalizeAttrPathsBeforeRegister(stageAttributes); + if (!stageIsNone) { + this->finalizeAttrPathsBeforeRegister(stageAttributes); + } stageAttributes->setIsClean(); From 27566b657778778d52c12a7e1239d53453e44032 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Mon, 20 May 2024 12:50:25 -0400 Subject: [PATCH 05/14] --populate fullpath setter with relpath setter if relpath setter exists on disk. --- src/esp/metadata/managers/AttributesManagerBase.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index a345d306fc..94e334d25b 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -729,6 +729,13 @@ void AttributesManager::filterAttribsFilenames( // Initialize potentially empty fields relPathSetter(curRelativePathName); fqPathSetter(curFullyQualifiedPathName); + // Check if expected relative filepath is accessible on disk (therefore is + // fully qualified) + bool relPathNameExists = CrPath::exists(curRelativePathName); + if (relPathNameExists) { + // Set the fully qualified value to be the found curRelPathName + fqPathSetter(curRelativePathName); + } // Get the attributes filepath that our desired filepath should be // relative to @@ -746,9 +753,7 @@ void AttributesManager::filterAttribsFilenames( // Check if expected relative filepath is accessible on disk (therefore is // fully qualified) - if (CrPath::exists(curRelativePathName)) { - // Set the fully qualified value to be the found curRelPathName - fqPathSetter(curRelativePathName); + if (relPathNameExists) { // Get new path relative to attrFilepath const std::string newRelFilepath = io::getPathRealtiveToAbsPath(curRelativePathName, attrFilepath); From d02ee873896b222d11c7d8c3a3b392235d94ae27 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Mon, 20 May 2024 15:18:54 -0400 Subject: [PATCH 06/14] --minor tweaks --- .../AbstractObjectAttributesManager.h | 2 +- .../metadata/managers/AttributesManagerBase.h | 2 +- .../managers/ObjectAttributesManager.cpp | 51 ++++++++++++------- .../SceneDatasetAttributesManager.cpp | 16 +++--- .../managers/StageAttributesManager.cpp | 49 +++++++++++------- 5 files changed, 74 insertions(+), 46 deletions(-) diff --git a/src/esp/metadata/managers/AbstractObjectAttributesManager.h b/src/esp/metadata/managers/AbstractObjectAttributesManager.h index eee11a9be7..483b99a5cc 100644 --- a/src/esp/metadata/managers/AbstractObjectAttributesManager.h +++ b/src/esp/metadata/managers/AbstractObjectAttributesManager.h @@ -150,7 +150,7 @@ class AbstractObjectAttributesManager : public AttributesManager { * @param handle String name of primitive asset attributes desired * @return whether handle exists or not in asset attributes library */ - bool isValidPrimitiveAttributes(const std::string& handle) { + bool isValidPrimitiveAttributes(const std::string& handle) const { return assetAttributesMgr_->getObjectLibHasHandle(handle); } diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index 94e334d25b..f10109aa54 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -756,7 +756,7 @@ void AttributesManager::filterAttribsFilenames( if (relPathNameExists) { // Get new path relative to attrFilepath const std::string newRelFilepath = - io::getPathRealtiveToAbsPath(curRelativePathName, attrFilepath); + io::getPathRelativeToAbsPath(curRelativePathName, attrFilepath); // save the new relative filepath relPathSetter(newRelFilepath); Cr::Utility::formatInto(dispString, dispString.size(), diff --git a/src/esp/metadata/managers/ObjectAttributesManager.cpp b/src/esp/metadata/managers/ObjectAttributesManager.cpp index c7a82fca1e..2272168268 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.cpp +++ b/src/esp/metadata/managers/ObjectAttributesManager.cpp @@ -315,26 +315,41 @@ void ObjectAttributesManager::finalizeAttrPathsBeforeRegister( // << objectTemplate->getFileDirectory() << "`"; // Render asset filename filter out path and set internal reference to full // filepaath - this->filterAttribsFilenames( - objectTemplate, objectTemplate->getRenderAssetHandle(), - objectTemplate->getRenderAssetFullPath(), - [objectTemplate](const std::string& renderAsset) { - objectTemplate->setRenderAssetHandle(renderAsset); - }, - [objectTemplate](const std::string& renderAsset) { - objectTemplate->setRenderAssetFullPath(renderAsset); - }); + // Render asset filename filter out path and set internal reference to full + // filepath + const std::string renderAssetHandle = objectTemplate->getRenderAssetHandle(); + if (!this->isValidPrimitiveAttributes(renderAssetHandle)) { + this->filterAttribsFilenames( + objectTemplate, renderAssetHandle, + objectTemplate->getRenderAssetFullPath(), + [objectTemplate](const std::string& renderAsset) { + objectTemplate->setRenderAssetHandle(renderAsset); + }, + [objectTemplate](const std::string& renderAsset) { + objectTemplate->setRenderAssetFullPath(renderAsset); + }); + } else { + // If handle refs a prim then just copy it over to full path + objectTemplate->setRenderAssetFullPath(renderAssetHandle); + } // Collision asset filename filter out path and set internal reference to // full filepaath - this->filterAttribsFilenames( - objectTemplate, objectTemplate->getCollisionAssetHandle(), - objectTemplate->getCollisionAssetFullPath(), - [objectTemplate](const std::string& colHndl) { - objectTemplate->setCollisionAssetHandle(colHndl); - }, - [objectTemplate](const std::string& colHndl) { - objectTemplate->setCollisionAssetFullPath(colHndl); - }); + const std::string collisionAssetHandle = + objectTemplate->getCollisionAssetHandle(); + if (!this->isValidPrimitiveAttributes(collisionAssetHandle)) { + this->filterAttribsFilenames( + objectTemplate, collisionAssetHandle, + objectTemplate->getCollisionAssetFullPath(), + [objectTemplate](const std::string& colHndl) { + objectTemplate->setCollisionAssetHandle(colHndl); + }, + [objectTemplate](const std::string& colHndl) { + objectTemplate->setCollisionAssetFullPath(colHndl); + }); + } else { + // If handle refs a prim then just copy it over to full path + objectTemplate->setCollisionAssetFullPath(collisionAssetHandle); + } // ESP_ERROR(Mn::Debug::Flag::NoSpace) // << "AFTER Obj `" << objectTemplateHandle << "`: Render fn `" diff --git a/src/esp/metadata/managers/SceneDatasetAttributesManager.cpp b/src/esp/metadata/managers/SceneDatasetAttributesManager.cpp index 403eea298b..bc461f3b6b 100644 --- a/src/esp/metadata/managers/SceneDatasetAttributesManager.cpp +++ b/src/esp/metadata/managers/SceneDatasetAttributesManager.cpp @@ -262,7 +262,7 @@ void SceneDatasetAttributesManager::readDatasetJSONCell( (key == "configs")) { // These keys have been processed already continue; - } // if has configs cell + } // if has paths, default_attributes or configs cell else { if (it->value.IsString()) { strKeyMap->emplace(key, it->value.GetString()); @@ -275,7 +275,6 @@ void SceneDatasetAttributesManager::readDatasetJSONCell( } } } // for each sub-cell within main cell - } else { // No map was passed - only applicable for // semantic_scene_descriptor_instances @@ -284,10 +283,10 @@ void SceneDatasetAttributesManager::readDatasetJSONCell( << "Unable to load semantic scene map due to destination " "map being null."; } - } - } // process unexpected member tags - } // if cell is an object - } // if cell exists + } // map passed to this function + } // process unexpected member tags + } // if cell is an object + } // if cell exists } // SceneDatasetAttributesManager::readDatasetJSONCell void SceneDatasetAttributesManager::validateMap( @@ -297,17 +296,18 @@ void SceneDatasetAttributesManager::validateMap( // now verify that all entries in map exist. If not replace entry with // dsDir-prepended entry for (std::pair& entry : map) { + const std::string key = entry.first; const std::string loc = entry.second; if (!Cr::Utility::Path::exists(loc)) { std::string newLoc = Cr::Utility::Path::join(dsDir, loc); if (!Cr::Utility::Path::exists(newLoc)) { ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "`" << tag << "` Value : `" << loc + << "`" << tag << "` Key : `" << key << "` Value : `" << loc << "` not found on disk as absolute path or relative to `" << dsDir << "`"; } else { // replace value with dataset-augmented absolute path - map[entry.first] = newLoc; + map[key] = newLoc; } } // loc does not exist } // for each loc diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index 4777a1fc7f..7a70bcb86c 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -484,26 +484,39 @@ void StageAttributesManager::finalizeAttrPathsBeforeRegister( // Render asset filename filter out path and set internal reference to full // filepath - this->filterAttribsFilenames( - stageAttributes, stageAttributes->getRenderAssetHandle(), - stageAttributes->getRenderAssetFullPath(), - [stageAttributes](const std::string& renderAsset) { - stageAttributes->setRenderAssetHandle(renderAsset); - }, - [stageAttributes](const std::string& renderAsset) { - stageAttributes->setRenderAssetFullPath(renderAsset); - }); + const std::string renderAssetHandle = stageAttributes->getRenderAssetHandle(); + if (!this->isValidPrimitiveAttributes(renderAssetHandle)) { + this->filterAttribsFilenames( + stageAttributes, renderAssetHandle, + stageAttributes->getRenderAssetFullPath(), + [stageAttributes](const std::string& renderAsset) { + stageAttributes->setRenderAssetHandle(renderAsset); + }, + [stageAttributes](const std::string& renderAsset) { + stageAttributes->setRenderAssetFullPath(renderAsset); + }); + } else { + // If handle refs a prim then just copy it over to full path + stageAttributes->setRenderAssetFullPath(renderAssetHandle); + } // Collision asset filename filter out path and set internal reference to // full filepaath - this->filterAttribsFilenames( - stageAttributes, stageAttributes->getCollisionAssetHandle(), - stageAttributes->getCollisionAssetFullPath(), - [stageAttributes](const std::string& colHndl) { - stageAttributes->setCollisionAssetHandle(colHndl); - }, - [stageAttributes](const std::string& colHndl) { - stageAttributes->setCollisionAssetFullPath(colHndl); - }); + const std::string collisionAssetHandle = + stageAttributes->getCollisionAssetHandle(); + if (!this->isValidPrimitiveAttributes(collisionAssetHandle)) { + this->filterAttribsFilenames( + stageAttributes, collisionAssetHandle, + stageAttributes->getCollisionAssetFullPath(), + [stageAttributes](const std::string& colHndl) { + stageAttributes->setCollisionAssetHandle(colHndl); + }, + [stageAttributes](const std::string& colHndl) { + stageAttributes->setCollisionAssetFullPath(colHndl); + }); + } else { + // If handle refs a prim then just copy it over to full path + stageAttributes->setCollisionAssetFullPath(collisionAssetHandle); + } // filter filepaths of full path qualifiers // Navmesh asset filename this->filterAttribsFilenames( From 1850d1a3c2a8a2e566133ed2cc200721d1b52b48 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Mon, 20 May 2024 15:29:37 -0400 Subject: [PATCH 07/14] --fix stage template->semantic template field mappings --- .../attributes/SceneDatasetAttributes.cpp | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp index 1f724472de..65a5cccc02 100644 --- a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp +++ b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp @@ -153,11 +153,12 @@ void SceneDatasetAttributes::createSemanticAttribsFromDS( std::string SceneDatasetAttributes::addSemanticSceneDescrPathEntry( const std::string& semanticHandle, const attributes::StageAttributes::ptr& stageAttributes) { - const auto ssdFilename = stageAttributes->getSemanticDescriptorFullPath(); - const auto semanticAssetFilename = - stageAttributes->getSemanticAssetFullPath(); - bool setSemanticAssetData = (semanticAssetFilename != ""); - bool setSSDFilename = (ssdFilename != ""); + const auto stageSSDFilename = + stageAttributes->getSemanticDescriptorFilename(); + const auto stageSemanticAssetFilename = + stageAttributes->getSemanticAssetHandle(); + bool setSemanticAssetData = (stageSemanticAssetFilename != ""); + bool setSSDFilename = (stageSSDFilename != ""); // create a semantic attributes if DNE with given handle this->createSemanticAttribsFromDS(semanticHandle, "Stage Attributes"); @@ -165,23 +166,22 @@ std::string SceneDatasetAttributes::addSemanticSceneDescrPathEntry( auto semanticAttr = semanticAttributesManager_->getObjectByHandle(semanticHandle); - if (setSemanticAssetData && - semanticAttr->getSemanticAssetFullPath().empty()) { + if (setSemanticAssetData && semanticAttr->getSemanticAssetHandle().empty()) { // asset handle specified, get all stage-specified data - semanticAttr->setSemanticAssetHandle( - stageAttributes->getSemanticAssetHandle()); - semanticAttr->setSemanticAssetFullPath(semanticAssetFilename); + semanticAttr->setSemanticAssetHandle(stageSemanticAssetFilename); semanticAttr->setSemanticAssetTypeEnum( stageAttributes->getSemanticAssetType()); semanticAttr->setSemanticOrientUp(stageAttributes->getSemanticOrientUp()); semanticAttr->setSemanticOrientFront( stageAttributes->getSemanticOrientFront()); } - if (setSSDFilename && semanticAttr->getSemanticDescriptorFullPath().empty()) { + if (setSSDFilename && semanticAttr->getSemanticDescriptorFilename().empty()) { // scene descriptor filename specified in stage, set in semantic // attributes. - semanticAttr->setSemanticDescriptorFilename(ssdFilename); + semanticAttr->setSemanticDescriptorFilename(stageSSDFilename); } + // Save changes and make sure appropriate filtering happens + semanticAttributesManager_->registerObject(semanticAttr, semanticHandle); return semanticAttr->getHandle(); } // SceneDatasetAttributes::addSemanticSceneDescrPathEntry @@ -198,6 +198,8 @@ void SceneDatasetAttributes::setSemanticAttrSSDFilenames( auto semanticAttr = semanticAttributesManager_->getObjectByHandle(semanticHandle); semanticAttr->setSemanticDescriptorFilename(ssdFilename); + // Save changes and make sure appropriate filtering happens + semanticAttributesManager_->registerObject(semanticAttr, semanticHandle); } } // SceneDatasetAttributes::setSemanticAttrSSDFilenames From a34bf939226dacda6f95bada1edf0676599929ff Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Mon, 20 May 2024 19:40:45 -0400 Subject: [PATCH 08/14] --fix issues with edge cases. --- .../attributes/SceneDatasetAttributes.cpp | 4 ++ .../metadata/managers/AOAttributesManager.cpp | 43 ++++++++--------- .../metadata/managers/AttributesManagerBase.h | 22 ++------- .../managers/ObjectAttributesManager.cpp | 24 +++++----- .../managers/ObjectAttributesManager.h | 20 ++++---- .../managers/SemanticAttributesManager.cpp | 30 ++++++------ .../managers/StageAttributesManager.cpp | 46 +++++++++---------- .../managers/StageAttributesManager.h | 20 ++++---- src/esp/sim/Simulator.cpp | 18 ++++---- src/tests/Mp3dTest.cpp | 2 + 10 files changed, 109 insertions(+), 120 deletions(-) diff --git a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp index 65a5cccc02..997030b04e 100644 --- a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp +++ b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp @@ -169,6 +169,8 @@ std::string SceneDatasetAttributes::addSemanticSceneDescrPathEntry( if (setSemanticAssetData && semanticAttr->getSemanticAssetHandle().empty()) { // asset handle specified, get all stage-specified data semanticAttr->setSemanticAssetHandle(stageSemanticAssetFilename); + semanticAttr->setSemanticAssetFullPath( + stageAttributes->getSemanticAssetFullPath()); semanticAttr->setSemanticAssetTypeEnum( stageAttributes->getSemanticAssetType()); semanticAttr->setSemanticOrientUp(stageAttributes->getSemanticOrientUp()); @@ -179,6 +181,8 @@ std::string SceneDatasetAttributes::addSemanticSceneDescrPathEntry( // scene descriptor filename specified in stage, set in semantic // attributes. semanticAttr->setSemanticDescriptorFilename(stageSSDFilename); + semanticAttr->setSemanticDescriptorFullPath( + stageAttributes->getSemanticDescriptorFullPath()); } // Save changes and make sure appropriate filtering happens semanticAttributesManager_->registerObject(semanticAttr, semanticHandle); diff --git a/src/esp/metadata/managers/AOAttributesManager.cpp b/src/esp/metadata/managers/AOAttributesManager.cpp index b6facf5c6c..a1f762d85f 100644 --- a/src/esp/metadata/managers/AOAttributesManager.cpp +++ b/src/esp/metadata/managers/AOAttributesManager.cpp @@ -203,16 +203,20 @@ AOAttributesManager::preRegisterObjectFinalize( << "`, but this file cannot be found, so registration is aborted."; return core::managedContainers::ManagedObjectPreregistration::Failed; } - + const std::string renderAssetHandle = + AOAttributesTemplate->getRenderAssetHandle(); // Furthermore, if 'skin' is specified as render_mode and no skin is // specified or the specified skin cannot be found, the registration should // also fail and the template should not be registered. - bool useSkinRenderMode = AOAttributesTemplate->getRenderMode() == - attributes::ArticulatedObjectRenderMode::Skin; + bool useSkinRenderMode = + (AOAttributesTemplate->getRenderMode() == + attributes::ArticulatedObjectRenderMode::Skin) || + ((AOAttributesTemplate->getRenderMode() == + attributes::ArticulatedObjectRenderMode::Default) && + (!renderAssetHandle.empty())); if (useSkinRenderMode) { - // if 'skin' render mode is specified as render mode - const std::string renderAssetHandle = - AOAttributesTemplate->getRenderAssetHandle(); + // if 'skin' render mode is specified as render mode or default and a skin + // is specified const std::string renderAssetFullPath = AOAttributesTemplate->getRenderAssetFullPath(); @@ -268,21 +272,18 @@ void AOAttributesManager::finalizeAttrPathsBeforeRegister( AOAttributesTemplate->setURDFFullPath(urdfAsset); }); - bool useSkinRenderMode = AOAttributesTemplate->getRenderMode() == - attributes::ArticulatedObjectRenderMode::Skin; - if (useSkinRenderMode) { - // Render asset filename filter out path and set internal reference to - // full filepath - this->filterAttribsFilenames( - AOAttributesTemplate, AOAttributesTemplate->getRenderAssetHandle(), - AOAttributesTemplate->getRenderAssetFullPath(), - [AOAttributesTemplate](const std::string& renderAsset) { - AOAttributesTemplate->setRenderAssetHandle(renderAsset); - }, - [AOAttributesTemplate](const std::string& renderAsset) { - AOAttributesTemplate->setRenderAssetFullPath(renderAsset); - }); - } + // Render asset filename filter out path and set internal reference to + // full filepath + this->filterAttribsFilenames( + AOAttributesTemplate, AOAttributesTemplate->getRenderAssetHandle(), + AOAttributesTemplate->getRenderAssetFullPath(), + [AOAttributesTemplate](const std::string& renderAsset) { + AOAttributesTemplate->setRenderAssetHandle(renderAsset); + }, + [AOAttributesTemplate](const std::string& renderAsset) { + AOAttributesTemplate->setRenderAssetFullPath(renderAsset); + }); + } // AOAttributesManager::finalizeAttrPathsBeforeRegister std::map diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index f10109aa54..dcc65d67ce 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -721,8 +721,8 @@ void AttributesManager::filterAttribsFilenames( // If both relative and fully qualified paths are empty, if (curRelativePathName.empty() && curFullyQualifiedPathName.empty()) { - ESP_ERROR() << "BOTH RELATIVE AND FQ PATHS ARE EMPTY Skipping: " - << dispString; + ESP_VERY_VERBOSE() << "BOTH RELATIVE AND FQ PATHS ARE EMPTY Skipping: " + << dispString; return; } @@ -741,7 +741,7 @@ void AttributesManager::filterAttribsFilenames( // relative to const std::string attrFilepath = attributes->getFileDirectory(); if (attrFilepath.empty()) { - ESP_ERROR() << "EMPTY FILEPATH Skipping : " << dispString; + ESP_VERY_VERBOSE() << "EMPTY FILEPATH Skipping : " << dispString; // if filepath is empty, do nothing. return; } @@ -762,20 +762,6 @@ void AttributesManager::filterAttribsFilenames( Cr::Utility::formatInto(dispString, dispString.size(), "|curRelPathName is FOUND/FQ|newRelFP `{}`", newRelFilepath); - } else if (curRelativePathName.empty()) { - Cr::Utility::formatInto(dispString, dispString.size(), - "|!!! curRelPathName is empty"); - } else { - // Current relative filepath cannot be found and is not empty, so assume - // it is already appropriately formatted - } - - if (CrPath::exists(curFullyQualifiedPathName)) { - // Current fully qualified pathname is found - Cr::Utility::formatInto(dispString, dispString.size(), - "|curFQPathName is FOUND/FQ"); - - // TODO : Populate relPathName with relative path pathname? } } // if attributes dir is set properly @@ -784,7 +770,7 @@ void AttributesManager::filterAttribsFilenames( "|NON-EXISTING FILEPATH `{}` ", attrFilepath); } - ESP_ERROR() << "\n" << dispString << "\n"; + ESP_VERY_VERBOSE() << dispString; } // filterAttribsFilenames template diff --git a/src/esp/metadata/managers/ObjectAttributesManager.cpp b/src/esp/metadata/managers/ObjectAttributesManager.cpp index 2272168268..c193e64d65 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.cpp +++ b/src/esp/metadata/managers/ObjectAttributesManager.cpp @@ -308,13 +308,11 @@ ObjectAttributesManager::preRegisterObjectFinalize( void ObjectAttributesManager::finalizeAttrPathsBeforeRegister( const attributes::ObjectAttributes::ptr& objectTemplate) const { - // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "BEFORE Obj `" << objectTemplateHandle << "`: Render fn `" - // << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" - // << objectTemplate->getCollisionAssetHandle() << "`| file dir `" - // << objectTemplate->getFileDirectory() << "`"; - // Render asset filename filter out path and set internal reference to full - // filepaath + ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) + << "BEFORE Obj `" << objectTemplate->getHandle() << "`: Render fn `" + << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" + << objectTemplate->getCollisionAssetHandle() << "`| file dir `" + << objectTemplate->getFileDirectory() << "`"; // Render asset filename filter out path and set internal reference to full // filepath const std::string renderAssetHandle = objectTemplate->getRenderAssetHandle(); @@ -351,12 +349,12 @@ void ObjectAttributesManager::finalizeAttrPathsBeforeRegister( objectTemplate->setCollisionAssetFullPath(collisionAssetHandle); } - // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "AFTER Obj `" << objectTemplateHandle << "`: Render fn `" - // << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" - // << objectTemplate->getCollisionAssetHandle() << "`| file dir `" - // << objectTemplate->getFileDirectory() << "`"; -} + ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) + << "AFTER Obj `" << objectTemplate->getHandle() << "`: Render fn `" + << objectTemplate->getRenderAssetHandle() << "`| Collision fn `" + << objectTemplate->getCollisionAssetHandle() << "`| file dir `" + << objectTemplate->getFileDirectory() << "`"; +} // ObjectAttributesManager::finalizeAttrPathsBeforeRegister void ObjectAttributesManager::postRegisterObjectHandling( int objectTemplateID, diff --git a/src/esp/metadata/managers/ObjectAttributesManager.h b/src/esp/metadata/managers/ObjectAttributesManager.h index 01525c8391..7e87fe141e 100644 --- a/src/esp/metadata/managers/ObjectAttributesManager.h +++ b/src/esp/metadata/managers/ObjectAttributesManager.h @@ -145,6 +145,16 @@ class ObjectAttributesManager physicsSynthObjTmpltLibByID_, subStr, contains, sorted); } + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::ObjectAttributes::ptr& attributes) const override; + // ======== End File-based and primitive-based partition functions ======== protected: @@ -225,16 +235,6 @@ class ObjectAttributesManager const std::string& attributesTemplateHandle, bool forceRegistration) override; - /** - * @brief This function will be called to finalize attributes' paths before - * registration, moving fully qualified paths to the appropriate hidden - * attribute fields. This can also be called without registration to make sure - * the paths specified in an attributes are properly configured. - * @param attributes The attributes to be filtered. - */ - void finalizeAttrPathsBeforeRegister( - const attributes::ObjectAttributes::ptr& attributes) const override; - /** * @brief This method will perform any final manager-related handling after * successfully registering an object. diff --git a/src/esp/metadata/managers/SemanticAttributesManager.cpp b/src/esp/metadata/managers/SemanticAttributesManager.cpp index 68bcc54e53..b00cac3b69 100644 --- a/src/esp/metadata/managers/SemanticAttributesManager.cpp +++ b/src/esp/metadata/managers/SemanticAttributesManager.cpp @@ -233,14 +233,13 @@ SemanticAttributesManager::preRegisterObjectFinalize( void SemanticAttributesManager::finalizeAttrPathsBeforeRegister( const attributes::SemanticAttributes::ptr& semanticAttributes) const { // filter filepaths of full path qualifiers - // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "BEFORE : Semantic Attr `" << semanticAttributes->getHandle() - // << "`| semantic asset fn `" - // << semanticAttributes->getSemanticAssetHandle() - // << "`| semantic descriptor fn `" - // << semanticAttributes->getSemanticDescriptorFilename() - // << "`| file directory `" << semanticAttributes->getFileDirectory() << - // "`"; + ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) + << "BEFORE : Semantic Attr `" << semanticAttributes->getHandle() + << "`| semantic asset fn `" + << semanticAttributes->getSemanticAssetHandle() + << "`| semantic descriptor fn `" + << semanticAttributes->getSemanticDescriptorFilename() + << "`| file directory `" << semanticAttributes->getFileDirectory() << "`"; // Semantic asset filename this->filterAttribsFilenames( semanticAttributes, semanticAttributes->getSemanticAssetHandle(), @@ -262,14 +261,13 @@ void SemanticAttributesManager::finalizeAttrPathsBeforeRegister( semanticAttributes->setSemanticDescriptorFullPath(semanticAsset); }); - // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "AFTER : Semantic Attr `" << semanticAttributes->getHandle() - // << "`| semantic asset fn `" - // << semanticAttributes->getSemanticAssetHandle() - // << "`| semantic descriptor fn `" - // << semanticAttributes->getSemanticDescriptorFilename() - // << "`| file directory `" << semanticAttributes->getFileDirectory() << - // "`"; + ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) + << "AFTER : Semantic Attr `" << semanticAttributes->getHandle() + << "`| semantic asset fn `" + << semanticAttributes->getSemanticAssetHandle() + << "`| semantic descriptor fn `" + << semanticAttributes->getSemanticDescriptorFilename() + << "`| file directory `" << semanticAttributes->getFileDirectory() << "`"; } // SemanticAttributesManager::finalizeAttrPathsBeforeRegister diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index 7a70bcb86c..8931fec66a 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -469,18 +469,17 @@ StageAttributesManager::preRegisterObjectFinalize( void StageAttributesManager::finalizeAttrPathsBeforeRegister( const attributes::StageAttributes::ptr& stageAttributes) const { - // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "BEFORE : Stage `" << stageAttributesHandle << "`: Render rel `" - // << stageAttributes->getRenderAssetHandle() << "`: Render FQ `" - // << stageAttributes->getRenderAssetFullPath() << "`| Collision rel `" - // << stageAttributes->getCollisionAssetHandle() << "`| Collision FQ `" - // << stageAttributes->getCollisionAssetFullPath() << "`| navmesh rel `" - // << stageAttributes->getNavmeshAssetHandle() - // << "`| semantic asset rel `" - // << stageAttributes->getSemanticAssetHandle() - // << "`| semantic descriptor rel `" - // << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" - // << stageAttributes->getFileDirectory() << "`"; + ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) + << "BEFORE : Stage `" << stageAttributes->getHandle() << "`: Render rel `" + << stageAttributes->getRenderAssetHandle() << "`: Render FQ `" + << stageAttributes->getRenderAssetFullPath() << "`| Collision rel `" + << stageAttributes->getCollisionAssetHandle() << "`| Collision FQ `" + << stageAttributes->getCollisionAssetFullPath() << "`| navmesh rel `" + << stageAttributes->getNavmeshAssetHandle() << "`| semantic asset rel `" + << stageAttributes->getSemanticAssetHandle() + << "`| semantic descriptor rel `" + << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" + << stageAttributes->getFileDirectory() << "`"; // Render asset filename filter out path and set internal reference to full // filepath @@ -549,18 +548,17 @@ void StageAttributesManager::finalizeAttrPathsBeforeRegister( stageAttributes->setSemanticDescriptorFullPath(ssd); }); - // ESP_ERROR(Mn::Debug::Flag::NoSpace) - // << "AFTER : Stage `" << stageAttributesHandle << "`: Render rel `" - // << stageAttributes->getRenderAssetHandle() << "`: Render FQ `" - // << stageAttributes->getRenderAssetFullPath() << "`| Collision rel `" - // << stageAttributes->getCollisionAssetHandle() << "`| Collision FQ `" - // << stageAttributes->getCollisionAssetFullPath() << "`| navmesh rel `" - // << stageAttributes->getNavmeshAssetHandle() - // << "`| semantic asset rel `" - // << stageAttributes->getSemanticAssetHandle() - // << "`| semantic descriptor rel `" - // << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" - // << stageAttributes->getFileDirectory() << "`"; + ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace) + << "AFTER : Stage `" << stageAttributes->getHandle() << "`: Render rel `" + << stageAttributes->getRenderAssetHandle() << "`: Render FQ `" + << stageAttributes->getRenderAssetFullPath() << "`| Collision rel `" + << stageAttributes->getCollisionAssetHandle() << "`| Collision FQ `" + << stageAttributes->getCollisionAssetFullPath() << "`| navmesh rel `" + << stageAttributes->getNavmeshAssetHandle() << "`| semantic asset rel `" + << stageAttributes->getSemanticAssetHandle() + << "`| semantic descriptor rel `" + << stageAttributes->getSemanticDescriptorFilename() << "`| file dir `" + << stageAttributes->getFileDirectory() << "`"; // Clear dirty flag from when asset handles are changed } diff --git a/src/esp/metadata/managers/StageAttributesManager.h b/src/esp/metadata/managers/StageAttributesManager.h index 5d48ffdd0b..24522d7779 100644 --- a/src/esp/metadata/managers/StageAttributesManager.h +++ b/src/esp/metadata/managers/StageAttributesManager.h @@ -79,6 +79,16 @@ class StageAttributesManager void setValsFromJSONDoc(attributes::StageAttributes::ptr attribs, const io::JsonGenericValue& jsonConfig) override; + /** + * @brief This function will be called to finalize attributes' paths before + * registration, moving fully qualified paths to the appropriate hidden + * attribute fields. This can also be called without registration to make sure + * the paths specified in an attributes are properly configured. + * @param attributes The attributes to be filtered. + */ + void finalizeAttrPathsBeforeRegister( + const attributes::StageAttributes::ptr& attributes) const override; + protected: /** * @brief Create and save default primitive asset-based object templates, @@ -153,16 +163,6 @@ class StageAttributesManager const std::string& StageAttributesHandle, bool forceRegistration) override; - /** - * @brief This function will be called to finalize attributes' paths before - * registration, moving fully qualified paths to the appropriate hidden - * attribute fields. This can also be called without registration to make sure - * the paths specified in an attributes are properly configured. - * @param attributes The attributes to be filtered. - */ - void finalizeAttrPathsBeforeRegister( - const attributes::StageAttributes::ptr& attributes) const override; - /** * @brief Not required for this manager. * diff --git a/src/esp/sim/Simulator.cpp b/src/esp/sim/Simulator.cpp index 3bd7d40917..bc2c0eb7a8 100644 --- a/src/esp/sim/Simulator.cpp +++ b/src/esp/sim/Simulator.cpp @@ -498,20 +498,20 @@ bool Simulator::instanceStageForSceneAttributes( // SemanticAttributes if (semanticAttr != nullptr) { const std::string semanticAttrSSDName = - semanticAttr->getSemanticDescriptorFullPath(); + semanticAttr->getSemanticDescriptorFilename(); const std::string semanticAttrAssetName = - semanticAttr->getSemanticAssetFullPath(); + semanticAttr->getSemanticAssetHandle(); // - Set stage semantic values if appropriate - this overrides whatever is // specified previoussly in stage attributes. if (semanticAttrSSDName != "") { - stageAttributes->setSemanticDescriptorFilename( - semanticAttr->getSemanticDescriptorFilename()); - stageAttributes->setSemanticDescriptorFullPath(semanticAttrSSDName); + stageAttributes->setSemanticDescriptorFilename(semanticAttrSSDName); + stageAttributes->setSemanticDescriptorFullPath( + semanticAttr->getSemanticDescriptorFullPath()); } if (semanticAttrAssetName != "") { - stageAttributes->setSemanticAssetHandle( - semanticAttr->getSemanticAssetHandle()); - stageAttributes->setSemanticAssetFullPath(semanticAttrAssetName); + stageAttributes->setSemanticAssetHandle(semanticAttrAssetName); + stageAttributes->setSemanticAssetFullPath( + semanticAttr->getSemanticAssetFullPath()); stageAttributes->setSemanticAssetTypeEnum( semanticAttr->getSemanticAssetType()); if (semanticAttr->getSemanticOrientFront() != @@ -525,6 +525,8 @@ bool Simulator::instanceStageForSceneAttributes( semanticAttr->getSemanticOrientUp()); } } + metadataMediator_->getStageAttributesManager() + ->finalizeAttrPathsBeforeRegister(stageAttributes); } // set visibility if explicitly specified in stage instance configs diff --git a/src/tests/Mp3dTest.cpp b/src/tests/Mp3dTest.cpp index 45e85459f2..44223877d7 100644 --- a/src/tests/Mp3dTest.cpp +++ b/src/tests/Mp3dTest.cpp @@ -36,6 +36,8 @@ void Mp3dTest::testLoad() { auto mp3dAttr = esp::metadata::attributes::SemanticAttributes::create("mp3dTestAttrs"); mp3dAttr->setSemanticDescriptorFilename(filename); + mp3dAttr->setSemanticDescriptorFullPath(filename); + esp::scene::SemanticScene house; const esp::quatf alignGravity = esp::quatf::FromTwoVectors(-esp::vec3f::UnitZ(), esp::geo::ESP_GRAVITY); From e46f73ce6951fef9d4a713fffb458b95708b8566 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Tue, 21 May 2024 09:16:02 -0400 Subject: [PATCH 09/14] --add python bindings for read-only fq paths and the filter func When a path is set by the user via the path/handle attributes properties, the filter function will copy the fully qualified path to the appropriate read-only property and attempt to transform the path to be relative to the location of the owning dataset's path structure. --- src/esp/bindings/AttributesBindings.cpp | 33 +++++++++++++++++++ .../bindings/AttributesManagersBindings.cpp | 9 +++-- .../metadata/managers/AttributesManagerBase.h | 10 +++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/esp/bindings/AttributesBindings.cpp b/src/esp/bindings/AttributesBindings.cpp index d415d76897..bbb2f1f0e8 100644 --- a/src/esp/bindings/AttributesBindings.cpp +++ b/src/esp/bindings/AttributesBindings.cpp @@ -452,12 +452,23 @@ void initAttributesBindings(py::module& m) { &ArticulatedObjectAttributes::setURDFPath, R"(Relative filepath of the URDF file used to create the Articulated Object described by this template.)") + .def_property_readonly( + "urdf_fullpath", &ArticulatedObjectAttributes::getURDFFullPath, + R"(Fully qualified filepath of the URDF file used to create the Articulated Object + described by this template. This filepath will only be available/accurate + after the owning attributes is registered)") .def_property( "render_asset_handle", &ArticulatedObjectAttributes::getRenderAssetHandle, &ArticulatedObjectAttributes::setRenderAssetHandle, R"(Handle of the asset used to render constructions built from this articulated object template.)") + .def_property_readonly( + "render_asset_fullpath", + &ArticulatedObjectAttributes::getRenderAssetFullPath, + R"(Fully qualified filepath of the asset used to render constructions built from + this template. This filepath will only be available/accurate + after the owning attributes is registered)") .def_property( "semantic_id", &ArticulatedObjectAttributes::getSemanticId, &ArticulatedObjectAttributes::setSemanticId, @@ -572,6 +583,18 @@ void initAttributesBindings(py::module& m) { &AbstractObjectAttributes::setCollisionAssetHandle, R"(Handle of the asset used to calculate collsions for constructions built from this template.)") + .def_property_readonly( + "render_asset_fullpath", + &AbstractObjectAttributes::getRenderAssetFullPath, + R"(Fully qualified filepath of the asset used to render constructions built from + this template. This filepath will only be available/accurate + after the owning attributes is registered)") + .def_property_readonly( + "collision_asset_fullpath", + &AbstractObjectAttributes::getCollisionAssetFullPath, + R"(Fully qualified filepath of the asset used to calculate collsions for constructions + built from this template. This filepath will only be available/accurate + after the owning attributes is registered)") .def_property( "shader_type", &AbstractObjectAttributes::getShaderType, &AbstractObjectAttributes::setShaderType, @@ -691,6 +714,11 @@ void initAttributesBindings(py::module& m) { &StageAttributes::setSemanticAssetHandle, R"(Handle of the asset used for semantic segmentation of stages built from this template.)") + .def_property_readonly( + "semantic_asset_fullpath", &StageAttributes::getSemanticAssetFullPath, + R"(Fully qualified filepath of the asset used for semantic segmentation of stages + built from this template. This filepath will only be available/accurate after + the owning attributes is registered)") .def_property_readonly( "semantic_asset_type", &StageAttributes::getSemanticAssetType, R"(Type of asset used for collision calculations for constructions @@ -705,6 +733,11 @@ void initAttributesBindings(py::module& m) { &StageAttributes::setSemanticDescriptorFilename, R"(Handle for file containing semantic type maps and hierarchy for constructions built from this template.)") + .def_property_readonly( + "house_fq_filename", &StageAttributes::getSemanticDescriptorFullPath, + R"(Fully qualified path of file containing semantic type maps and hierarchy for + constructions built from this template. This filepath will only be available/accurate + after the owning attributes is registered)") .def_property( "frustum_culling", &StageAttributes::getFrustumCulling, &StageAttributes::setFrustumCulling, diff --git a/src/esp/bindings/AttributesManagersBindings.cpp b/src/esp/bindings/AttributesManagersBindings.cpp index 1ef067a59c..0572e8761d 100644 --- a/src/esp/bindings/AttributesManagersBindings.cpp +++ b/src/esp/bindings/AttributesManagersBindings.cpp @@ -244,8 +244,7 @@ void declareBaseAttributesManager(py::module& m, &MgrClass::getFirstMatchingObjectOrCopyByHandle), ("This returns a copy of the first " + attrType + " template containing the passed handle substring if any exist, " - "and NULL " - "if none could be found.") + "and NULL if none could be found.") .c_str(), "handle_substr"_a) .def("get_templates_by_handle_substring", @@ -258,6 +257,12 @@ void declareBaseAttributesManager(py::module& m, "on the value of boolean contains.") .c_str(), "search_str"_a = "", "contains"_a = true) + .def("filter_filepaths", &MgrClass::finalizeAttrPathsBeforeRegister, + ("This attempts to filter any filenames in the passed " + attrType + + " template so that the fields that would be saved to file would " + "only contain relative paths.") + .c_str(), + "attributes"_a) .def("save_template_by_handle", static_cast( &MgrClass::saveManagedObjectToFile), diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index dcc65d67ce..a8a843c8d0 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -714,8 +714,7 @@ void AttributesManager::filterAttribsFilenames( std::string dispString = Cr::Utility::formatString( "AttrHandle `{}` class :`{}`|curRelPathName `{}`|curFQPathName " - ":`{}`|nonEmptyRel " - "`{}`|nonEmptyFQ :`{}`", + ":`{}`|nonEmptyRel proposal :`{}`|nonEmptyFQ proposal :`{}`", attributes->getHandle(), attributes->getClassKey(), curRelPathName, curFQPathName, curRelativePathName, curFullyQualifiedPathName); @@ -749,7 +748,7 @@ void AttributesManager::filterAttribsFilenames( // verify attributes filepath exists if (CrPath::isDirectory(attrFilepath)) { Cr::Utility::formatInto(dispString, dispString.size(), - "|attr Filepath `{}`", attrFilepath); + "|attributes Filepath :`{}`", attrFilepath); // Check if expected relative filepath is accessible on disk (therefore is // fully qualified) @@ -760,14 +759,15 @@ void AttributesManager::filterAttribsFilenames( // save the new relative filepath relPathSetter(newRelFilepath); Cr::Utility::formatInto(dispString, dispString.size(), - "|curRelPathName is FOUND/FQ|newRelFP `{}`", + "|curRelPathName is FOUND/FQ|newRelFP :`{}`", newRelFilepath); } } // if attributes dir is set properly else { Cr::Utility::formatInto(dispString, dispString.size(), - "|NON-EXISTING FILEPATH `{}` ", attrFilepath); + "|FILEPATH DOES NOT EXIST IN SYSTEM :`{}` ", + attrFilepath); } ESP_VERY_VERBOSE() << dispString; From 8fb33bd54cb9404b2197dab1961a86a57590bf80 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Tue, 21 May 2024 09:23:07 -0400 Subject: [PATCH 10/14] --fix attributes managers test to use appropriate filepath --- tests/test_attributes_managers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_attributes_managers.py b/tests/test_attributes_managers.py index 48dd328568..34d1bacd06 100644 --- a/tests/test_attributes_managers.py +++ b/tests/test_attributes_managers.py @@ -307,7 +307,7 @@ def test_stage_attributes_managers(): assert template0.gravity == mn.Vector3(0.0, -9.8, 0.0) # verify creating new template - perform_add_blank_template_test(stage_mgr, template0.render_asset_handle) + perform_add_blank_template_test(stage_mgr, template0.render_asset_fullpath) def test_object_attributes_managers(): @@ -323,7 +323,7 @@ def test_object_attributes_managers(): template0, _ = perform_general_tests(obj_mgr, rand_obj_handle) # verify creating new template - perform_add_blank_template_test(obj_mgr, template0.render_asset_handle) + perform_add_blank_template_test(obj_mgr, template0.render_asset_fullpath) def perform_asset_attrib_mgr_tests(attr_mgr, default_attribs, legalVal, illegalVal): From dc3a2098ebee50c535c07adedda8ff4f7dc4433f Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Tue, 21 May 2024 09:26:12 -0400 Subject: [PATCH 11/14] --fix simulator python test to query appropriate filepath --- tests/test_simulator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_simulator.py b/tests/test_simulator.py index f25d39ab4c..b56d897e95 100644 --- a/tests/test_simulator.py +++ b/tests/test_simulator.py @@ -250,8 +250,10 @@ def test_object_template_editing(): assert obj.object_id != habitat_sim.stage_id # test getting initialization templates + # NOTE : After template is registered, the read-only 'render_asset_fullpath' + # field holds the fully qualified path stage_init_template = sim.get_stage_initialization_template() - assert stage_init_template.render_asset_handle == cfg_settings["scene"] + assert stage_init_template.render_asset_fullpath == cfg_settings["scene"] obj_init_template = obj.creation_attributes assert obj_init_template.render_asset_handle.endswith("sphere.glb") From 4ca3b66b44234222563f38f21f8ffaff6f7fe289 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Thu, 23 May 2024 10:16:08 -0400 Subject: [PATCH 12/14] --minor fix - error message format --- src/esp/scene/SemanticScene.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/esp/scene/SemanticScene.h b/src/esp/scene/SemanticScene.h index d978cdc594..8cbc752f98 100644 --- a/src/esp/scene/SemanticScene.h +++ b/src/esp/scene/SemanticScene.h @@ -326,8 +326,8 @@ class SemanticScene { const std::string& srcFunc) { if (!Cr::Utility::Path::exists(filename)) { ESP_WARNING(Mn::Debug::Flag::NoSpace) - << "::" << srcFunc << ": File" << filename - << "does not exist. Aborting load."; + << "::" << srcFunc << ": File `" << filename + << "` does not exist. Aborting load."; return false; } return true; From 60852b927bc31e6822e63415f5ab76010bd1f288 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Thu, 23 May 2024 10:22:12 -0400 Subject: [PATCH 13/14] --address stage collision asset bug If no collision asset was given the given render asset handles should be used. --- .../metadata/managers/AttributesManagerBase.h | 75 ++++++++++++------- .../managers/StageAttributesManager.cpp | 22 +++--- 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index a8a843c8d0..d22106238d 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -707,71 +707,92 @@ void AttributesManager::filterAttribsFilenames( const std::string& curFQPathName, const std::function& relPathSetter, const std::function& fqPathSetter) const { + // Get substitute pathnames if either target is empty const std::string curFullyQualifiedPathName = (curFQPathName.empty() ? curRelPathName : curFQPathName); const std::string curRelativePathName = (curRelPathName.empty() ? curFullyQualifiedPathName : curRelPathName); - - std::string dispString = Cr::Utility::formatString( - "AttrHandle `{}` class :`{}`|curRelPathName `{}`|curFQPathName " - ":`{}`|nonEmptyRel proposal :`{}`|nonEmptyFQ proposal :`{}`", - attributes->getHandle(), attributes->getClassKey(), curRelPathName, - curFQPathName, curRelativePathName, curFullyQualifiedPathName); - - // If both relative and fully qualified paths are empty, + // Verbose Debug string - only build if we have appropriate logging enabled. + std::string dispString{""}; + if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::VeryVerbose)) { + dispString = Cr::Utility::formatString( + "AttrHandle `{}` class :`{}`|Arg RelPathname `{}`|Arg FQPathName " + ":`{}`|Rel proposal :`{}`|FQ proposal :`{}`", + attributes->getHandle(), attributes->getClassKey(), curRelPathName, + curFQPathName, curRelativePathName, curFullyQualifiedPathName); + } + // If both relative and fully qualified paths are empty, skip further + // processing. if (curRelativePathName.empty() && curFullyQualifiedPathName.empty()) { ESP_VERY_VERBOSE() << "BOTH RELATIVE AND FQ PATHS ARE EMPTY Skipping: " << dispString; return; } - // Initialize potentially empty fields + // Initialize potentially empty field. relPathSetter(curRelativePathName); - fqPathSetter(curFullyQualifiedPathName); // Check if expected relative filepath is accessible on disk (therefore is // fully qualified) bool relPathNameExists = CrPath::exists(curRelativePathName); if (relPathNameExists) { - // Set the fully qualified value to be the found curRelPathName + if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::VeryVerbose)) { + Cr::Utility::formatInto(dispString, dispString.size(), + "|Rel proposal is FOUND/FQ"); + } + // Set the fully qualified value to be the curRelativePathName since it + // exists in the filesystem. fqPathSetter(curRelativePathName); + } else { + // initialize fully-qualified name if empty + fqPathSetter(curFullyQualifiedPathName); } // Get the attributes filepath that our desired filepath should be - // relative to + // relative to. If this is empty or unknown then we have no path to set the + // target configuration path relative to and so we will preserve whatever is + // currently set as the path in the target relative field. This potentially + // fully qualified path will also be saved to file should the owning + // attributes be saved. const std::string attrFilepath = attributes->getFileDirectory(); if (attrFilepath.empty()) { ESP_VERY_VERBOSE() << "EMPTY FILEPATH Skipping : " << dispString; - // if filepath is empty, do nothing. + // if filepath is empty, do nothing more. return; } - // verify attributes filepath exists + // Verify non-empty attributes filepath exists in the filesystem if (CrPath::isDirectory(attrFilepath)) { - Cr::Utility::formatInto(dispString, dispString.size(), - "|attributes Filepath :`{}`", attrFilepath); + if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::VeryVerbose)) { + Cr::Utility::formatInto(dispString, dispString.size(), + "|attributes Filepath :`{}`", attrFilepath); + } - // Check if expected relative filepath is accessible on disk (therefore is - // fully qualified) + // If expected relative filepath is accessible on disk, and therefore is + // fully qualified, then make relative to attributes filepath. if (relPathNameExists) { // Get new path relative to attrFilepath const std::string newRelFilepath = io::getPathRelativeToAbsPath(curRelativePathName, attrFilepath); // save the new relative filepath relPathSetter(newRelFilepath); - Cr::Utility::formatInto(dispString, dispString.size(), - "|curRelPathName is FOUND/FQ|newRelFP :`{}`", - newRelFilepath); + if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::VeryVerbose)) { + Cr::Utility::formatInto(dispString, dispString.size(), + "|New Rel proposal :`{}`", newRelFilepath); + } } - } // if attributes dir is set properly else { - Cr::Utility::formatInto(dispString, dispString.size(), - "|FILEPATH DOES NOT EXIST IN SYSTEM :`{}` ", - attrFilepath); + // This means the attributes filepath is not empty but is not found on + // disk either, probably indicative of a much bigger issue. + if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::VeryVerbose)) { + Cr::Utility::formatInto(dispString, dispString.size(), + "|ATTR PATH DOES NOT EXIST IN SYSTEM :`{}` ", + attrFilepath); + } } ESP_VERY_VERBOSE() << dispString; -} // filterAttribsFilenames +} // AttributesManager::filterAttribsFilenames template template @@ -807,7 +828,7 @@ void AttributesManager::setEnumStringFromJsonDoc( valueSetter("unspecified"); } } -} // setEnumStringFromJsonDoc +} // AttributesManager::setEnumStringFromJsonDoc } // namespace managers } // namespace metadata diff --git a/src/esp/metadata/managers/StageAttributesManager.cpp b/src/esp/metadata/managers/StageAttributesManager.cpp index 8931fec66a..9c786856a4 100644 --- a/src/esp/metadata/managers/StageAttributesManager.cpp +++ b/src/esp/metadata/managers/StageAttributesManager.cpp @@ -441,25 +441,25 @@ StageAttributesManager::preRegisterObjectFinalize( stageAttributes->setCollisionAssetFullPath("NONE"); } else { // Else, means no collision data specified, use specified render data - ESP_DEBUG() - << "Collision asset template handle :" << collisionAssetHandle - << "specified in stage template with handle :" << stageAttributesHandle - << "does not correspond to any existing file or primitive render " - "asset. Overriding with given render asset handle :" - << renderAssetHandle << "."; + ESP_DEBUG(Mn::Debug::Flag::NoSpace) + << "Collision asset template handle : `" << collisionAssetHandle + << "` specified in stage template with handle : `" + << stageAttributesHandle + << "` does not correspond to any existing file or known primitive " + "asset. Overriding with given render asset handle : `" + << renderAssetHandle << "`."; stageAttributes->setCollisionAssetHandle( - stageAttributes->getCollisionAssetHandle()); + stageAttributes->getRenderAssetHandle()); stageAttributes->setCollisionAssetFullPath( - stageAttributes->getCollisionAssetFullPath()); + stageAttributes->getRenderAssetFullPath()); stageAttributes->setCollisionAssetIsPrimitive( stageAttributes->getRenderAssetIsPrimitive()); } // filter all paths properly so that the handles don't have filepaths and the // accessors are hidden fields - if (!stageIsNone) { - this->finalizeAttrPathsBeforeRegister(stageAttributes); - } + + this->finalizeAttrPathsBeforeRegister(stageAttributes); stageAttributes->setIsClean(); From 72e4b41d34d69005d934d9fb39859210dcc738f9 Mon Sep 17 00:00:00 2001 From: John Turner <7strbass@gmail.com> Date: Thu, 23 May 2024 12:44:54 -0400 Subject: [PATCH 14/14] --reviewer suggestions; speeeling. --- src/esp/metadata/attributes/SemanticAttributes.cpp | 2 +- src/esp/metadata/attributes/SemanticAttributes.h | 2 +- src/esp/metadata/managers/AssetAttributesManager.h | 2 +- src/esp/metadata/managers/AttributesManagerBase.h | 6 +++--- src/tests/AttributesManagersTest.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/esp/metadata/attributes/SemanticAttributes.cpp b/src/esp/metadata/attributes/SemanticAttributes.cpp index 00807fc733..be6d02c304 100644 --- a/src/esp/metadata/attributes/SemanticAttributes.cpp +++ b/src/esp/metadata/attributes/SemanticAttributes.cpp @@ -181,7 +181,7 @@ std::string SemanticAttributes::getObjectInfoInternal() const { // std::string res = ""; // TODO do this for any SemanticAttributes level values std::string res = Cr::Utility::formatString( - "\nSemantic Scene Descriptor Filename,Semantic Mesh Assset,\n{},{}\n", + "\nSemantic Scene Descriptor Filename,Semantic Mesh Asset,\n{},{}\n", getSemanticDescriptorFilename(), getSemanticAssetHandle()); int iter = 0; diff --git a/src/esp/metadata/attributes/SemanticAttributes.h b/src/esp/metadata/attributes/SemanticAttributes.h index 6775dcc198..809b6eac0b 100644 --- a/src/esp/metadata/attributes/SemanticAttributes.h +++ b/src/esp/metadata/attributes/SemanticAttributes.h @@ -218,7 +218,7 @@ class SemanticAttributes : public AbstractAttributes { } /** - * @brief Set the retlative Filename to the semantic texture mesh, if one + * @brief Set the relative Filename to the semantic texture mesh, if one * exists. */ void setSemanticAssetHandle(const std::string& semanticAssetHandle) { diff --git a/src/esp/metadata/managers/AssetAttributesManager.h b/src/esp/metadata/managers/AssetAttributesManager.h index 705c861e6e..4dcc3a2cd8 100644 --- a/src/esp/metadata/managers/AssetAttributesManager.h +++ b/src/esp/metadata/managers/AssetAttributesManager.h @@ -568,7 +568,7 @@ class AssetAttributesManager } // AssetAttributeManager::createPrimAttributes /** - * @brief Any Assset-attributes-specific resetting that needs to happen on + * @brief Any Asset-attributes-specific resetting that needs to happen on * reset. */ void resetFinalize() override { diff --git a/src/esp/metadata/managers/AttributesManagerBase.h b/src/esp/metadata/managers/AttributesManagerBase.h index d22106238d..6f5da31bf4 100644 --- a/src/esp/metadata/managers/AttributesManagerBase.h +++ b/src/esp/metadata/managers/AttributesManagerBase.h @@ -249,8 +249,8 @@ class AttributesManager : public ManagedFileBasedContainer { protected: /** * @brief Called internally right before attribute registration. Filepaths - * in the json configs for Habitat Datasets are specified relative to the - * location of the config in the file hierarchy. As the config is loaded, + * in the json configs for Habitat SceneDatasets are specified relative to + * the location of the config in the file hierarchy. As the config is loaded, * these filepaths will be fully qualified with absolute paths so that they * can be easily found and consumed on command. However, saving fully * qualified filepaths to JSON configs is undesirable. @@ -264,7 +264,7 @@ class AttributesManager : public ManagedFileBasedContainer { * * * It is assumed that what is passed to this function always referneces a - * filepath, so if, for example, this is called on a render asseet filepath, + * filepath, so if, for example, this is called on a render asset filepath, * it is assumed that that filepath does not reference a primitive * (non-file-based) asset. * diff --git a/src/tests/AttributesManagersTest.cpp b/src/tests/AttributesManagersTest.cpp index 5ddcd72110..dc8d4b756f 100644 --- a/src/tests/AttributesManagersTest.cpp +++ b/src/tests/AttributesManagersTest.cpp @@ -928,7 +928,7 @@ void AttributesManagersTest::testPrimitiveAssetAttributes() { // test that a new template can be created from the specified handles testAssetAttributesTemplateCreateFromHandle(uvSphereWireframeHandle); } -} // AttributesManagersTest::AsssetAttributesManagerGetAndModify test +} // AttributesManagersTest::AssetAttributesManagerGetAndModify test void AttributesManagersTest::testPrimitiveBasedObjectAttributes() { // get all handles of templates for primitive-based render objects