Skip to content

Commit

Permalink
--[BE Week] Better Attributes Handle search efficiency; Viewer.cpp/Vi…
Browse files Browse the repository at this point in the history
…ewer.py text render fixes (#2279)

* --add missing articulated object attributes verification support
--streamline process
* --speed up search by verifying target length before setting lowercase.
* --update viewer glyph rendering.
Also, set python enable, define and subsequently disable python viewer text blend in text print function
  • Loading branch information
jturner65 committed Dec 12, 2023
1 parent 5ca61eb commit d46492a
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 70 deletions.
19 changes: 12 additions & 7 deletions examples/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def __init__(self, sim_settings: Dict[str, Any]) -> None:
)

# Glyphs we need to render everything
self.glyph_cache = text.GlyphCache(mn.Vector2i(256))
self.glyph_cache = text.GlyphCache(mn.Vector2i(256), mn.Vector2i(1))
self.display_font.fill_glyph_cache(
self.glyph_cache,
string.ascii_lowercase
Expand Down Expand Up @@ -149,12 +149,7 @@ def __init__(self, sim_settings: Dict[str, Any]) -> None:
)
self.shader = shaders.VectorGL2D()

# make magnum text background transparent
mn.gl.Renderer.enable(mn.gl.Renderer.Feature.BLENDING)
mn.gl.Renderer.set_blend_function(
mn.gl.Renderer.BlendFunction.ONE,
mn.gl.Renderer.BlendFunction.ONE_MINUS_SOURCE_ALPHA,
)
# Set blend function
mn.gl.Renderer.set_blend_equation(
mn.gl.Renderer.BlendEquation.ADD, mn.gl.Renderer.BlendEquation.ADD
)
Expand Down Expand Up @@ -899,6 +894,13 @@ def exit_event(self, event: Application.ExitEvent):
exit(0)

def draw_text(self, sensor_spec):
# make magnum text background transparent for text
mn.gl.Renderer.enable(mn.gl.Renderer.Feature.BLENDING)
mn.gl.Renderer.set_blend_function(
mn.gl.Renderer.BlendFunction.ONE,
mn.gl.Renderer.BlendFunction.ONE_MINUS_SOURCE_ALPHA,
)

self.shader.bind_vector_texture(self.glyph_cache.texture)
self.shader.transformation_projection_matrix = self.window_text_transform
self.shader.color = [1.0, 1.0, 1.0]
Expand All @@ -919,6 +921,9 @@ def draw_text(self, sensor_spec):
)
self.shader.draw(self.window_text.mesh)

# Disable blending for text
mn.gl.Renderer.disable(mn.gl.Renderer.Feature.BLENDING)

def print_help_text(self) -> None:
"""
Print the Key Command help text.
Expand Down
5 changes: 3 additions & 2 deletions src/esp/core/managedContainers/ManagedContainerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ std::vector<std::string> getHandlesBySubStringPerTypeInternal(
mapOfHandles.begin();
iter != mapOfHandles.end(); ++iter) {
std::string rawKey = std::get<Idx>(*iter);
std::string key = Cr::Utility::String::lowercase(rawKey);
// be sure that key is big enough to search in (otherwise find has
// undefined behavior)
if (key.length() < strSize) {
if (rawKey.length() < strSize) {
continue;
}
std::string key = Cr::Utility::String::lowercase(rawKey);

bool found = (std::string::npos != key.find(strToLookFor));
if (found == contains) {
// if found and searching for contains, or not found and searching for
Expand Down
8 changes: 4 additions & 4 deletions src/esp/core/managedContainers/ManagedContainerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ class ManagedContainerBase {
const std::string& name) const;

/**
* @brief Get a list of all managed objects of passed type whose origin
* handles contain substr, ignoring subStr's case.
* @brief Get a list of all managed objects' handles of passed type whose
* origin handles contain substr, ignoring subStr's case.
*
* This version works on std::unordered_map<int,std::string> maps' values.
* @param mapOfHandles map containing the desired managed object handles
Expand All @@ -400,8 +400,8 @@ class ManagedContainerBase {
bool sorted) const;

/**
* @brief Get a list of all managed objects of passed type whose origin
* handles contain substr, ignoring subStr's case.
* @brief Get a list of all managed objects' handles of passed type whose
* origin handles contain substr, ignoring subStr's case.
*
* This version works on std::unordered_map<std::string,
* std::set<std::string>> maps's keys.
Expand Down
17 changes: 17 additions & 0 deletions src/esp/metadata/MetadataMediator.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,23 @@ class MetadataMediator {
return getActiveDSAttribs()->getNamedObjectAttributesCopy(objAttrName);
} // getNamedObjectAttributesCopy

/**
* @brief Returns articulated object attributes corresponding to passed handle
* as substring. Assumes articulated object attributes with @p artObjAttrName
* as substring exists in current dataset.
* @param artObjAttrName substring to handle of articulated object instance
* attributes that exists in current active dataset. The attributes will be
* found via substring search, so the name is expected to be sufficiently
* restrictive to have exactly 1 match in dataset.
* @return smart pointer to articulated object attributes if exists, nullptr
* otherwise.
*/
attributes::ArticulatedObjectAttributes::ptr
getNamedArticulatedObjectAttributesCopy(const std::string& artObjAttrName) {
return getActiveDSAttribs()->getNamedArticulatedObjectAttributesCopy(
artObjAttrName);
} // getNamedArticulatedObjectAttributesCopy

/**
* @brief Returns a lightsetup object configured by the attributes whose
* handle contains the passed @p lightSetupName
Expand Down
95 changes: 64 additions & 31 deletions src/esp/metadata/attributes/SceneDatasetAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,23 @@ SceneDatasetAttributes::SceneDatasetAttributes(
bool SceneDatasetAttributes::addNewSceneInstanceToDataset(
const attributes::SceneInstanceAttributes::ptr& sceneInstance) {
// info display message prefix
std::string infoPrefix = Cr::Utility::formatString(
const std::string infoPrefix = Cr::Utility::formatString(
"Dataset : '{}' : ", this->getSimplifiedHandle());

const std::string sceneInstanceName = sceneInstance->getHandle();
// verify stage in sceneInstance (required) exists in SceneDatasetAttributes,
// and if not, add it.
const auto& stageInstance = sceneInstance->getStageInstance();
const std::string stageHandle = stageInstance->getHandle();
const std::string fullStageName =
getFullAttrNameFromStr(stageHandle, stageAttributesManager_);
if (fullStageName == "") {
ESP_DEBUG(Mn::Debug::Flag::NoSpace)
// Check if present and if not create default.
if (stageAttributesManager_->getFullAttrNameFromStr(stageHandle) == "") {
ESP_WARNING(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Stage Attributes '" << stageHandle
<< "' specified in Scene Attributes but does not exist in dataset, so "
"creating.";
<< "' specified in Scene Attributes but does not exist in dataset, "
"so creating default.";
stageAttributesManager_->createObject(stageHandle, true);
} else {
ESP_DEBUG(Mn::Debug::Flag::NoSpace)
ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Stage Attributes '" << stageHandle
<< "' specified in Scene Attributes exists in dataset library.";
}
Expand All @@ -57,20 +56,38 @@ bool SceneDatasetAttributes::addNewSceneInstanceToDataset(
auto objectInstances = sceneInstance->getObjectInstances();
for (const auto& objInstance : objectInstances) {
const std::string objHandle = objInstance->getHandle();
const std::string fullObjHandle =
getFullAttrNameFromStr(objHandle, objectAttributesManager_);
if (fullObjHandle == "") {
ESP_DEBUG(Mn::Debug::Flag::NoSpace)
if (objectAttributesManager_->getFullAttrNameFromStr(objHandle) == "") {
ESP_WARNING(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Object Attributes '" << objHandle
<< "' specified in Scene Attributes but does not exist in "
"dataset, so creating.";
<< "' specified in Scene Attributes but does not exist in dataset, "
"so creating default.";

objectAttributesManager_->createObject(objHandle, true);
} else {
ESP_DEBUG(Mn::Debug::Flag::NoSpace)
ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Object Attributes '" << objHandle
<< "' specified in Scene Attributes exists in dataset library.";
}
}
// verify each articulated object in sceneInstance exists in
// SceneDatasetAttributes
auto artObjectInstances = sceneInstance->getArticulatedObjectInstances();
for (const auto& artObjInstance : artObjectInstances) {
const std::string artObjHandle = artObjInstance->getHandle();

// Check if present and if not create default.
if (artObjAttributesManager_->getFullAttrNameFromStr(artObjHandle) == "") {
ESP_WARNING(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Articulated Object Attributes '" << artObjHandle
<< "' specified in Scene Attributes but does not exist in dataset, "
"so creating default.";
artObjAttributesManager_->createObject(artObjHandle, true);
} else {
ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Articulated Object Attributes '" << artObjHandle
<< "' specified in Scene Attributes exists in dataset library.";
}
}

// verify lighting
std::string lightHandle = sceneInstance->getLightingHandle();
Expand All @@ -81,29 +98,31 @@ bool SceneDatasetAttributes::addNewSceneInstanceToDataset(
if (lightHandle.empty()) {
lightHandle = sceneInstanceName;
}

const std::string fullLightLayoutAttrName =
getFullAttrNameFromStr(lightHandle, lightLayoutAttributesManager_);
if (fullLightLayoutAttrName == "") {
ESP_DEBUG(Mn::Debug::Flag::NoSpace)
// Check if lighting attributes specified is present and if not create
// default.
if (lightLayoutAttributesManager_->getFullAttrNameFromStr(lightHandle) ==
"") {
ESP_WARNING(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Lighting Layout Attributes '" << lightHandle
<< "' specified in Scene Attributes but does not exist in dataset, so "
"creating.";
<< "' specified in Scene Attributes but does not exist in dataset, "
"so creating default.";
lightLayoutAttributesManager_->createObject(lightHandle, true);
} else {
ESP_DEBUG() << infoPrefix << "Lighting Layout Attributes" << lightHandle
<< "specified in Scene Attributes exists in dataset library.";
ESP_VERY_VERBOSE(Mn::Debug::Flag::NoSpace)
<< infoPrefix << "Lighting Layout Attributes '" << lightHandle
<< "' specified in Scene Attributes exists in dataset library.";
}

const std::string fullSceneInstanceName = getFullAttrNameFromStr(
sceneInstanceName, sceneInstanceAttributesManager_);

const std::string fullSceneInstanceName =
sceneInstanceAttributesManager_->getFullAttrNameFromStr(
sceneInstanceName);
// add scene attributes to scene attributes manager
if (fullSceneInstanceName == "") {
ESP_DEBUG() << infoPrefix << "Scene Attributes" << sceneInstanceName
<< "does not exist in dataset so adding.";
ESP_VERY_VERBOSE() << infoPrefix << "Scene Attributes" << sceneInstanceName
<< "does not exist in dataset so adding.";
sceneInstanceAttributesManager_->registerObject(sceneInstance);
}

return true;
} // SceneDatasetAttributes::addSceneInstanceToDataset

Expand Down Expand Up @@ -168,7 +187,7 @@ SceneDatasetAttributes::getNamedStageAttributesCopy(
// do a substring search to find actual stage attributes and return first
// attributes found; if does not exist, name will be empty. return nullptr
auto fullStageName =
getFullAttrNameFromStr(stageAttrName, stageAttributesManager_);
stageAttributesManager_->getFullAttrNameFromStr(stageAttrName);
// fullStageName will be empty if not found
if (fullStageName == "") {
return nullptr;
Expand All @@ -182,14 +201,28 @@ SceneDatasetAttributes::getNamedObjectAttributesCopy(
// do a substring search to find actual object attributes and return first
// attributes found; if does not exist, name will be empty. return nullptr
auto fullObjName =
getFullAttrNameFromStr(objAttrName, objectAttributesManager_);
objectAttributesManager_->getFullAttrNameFromStr(objAttrName);
// fullObjName will be empty if not found
if (fullObjName == "") {
return nullptr;
}
return objectAttributesManager_->getObjectCopyByHandle(fullObjName);
} // SceneDatasetAttributes::getNamedObjectAttributesCopy

attributes::ArticulatedObjectAttributes::ptr
SceneDatasetAttributes::getNamedArticulatedObjectAttributesCopy(
const std::string& artObjAttrName) {
// do a substring search to find actual object attributes and return first
// attributes found; if does not exist, name will be empty. return nullptr
auto fullArtObjName =
artObjAttributesManager_->getFullAttrNameFromStr(artObjAttrName);
// fullObjName will be empty if not found
if (fullArtObjName == "") {
return nullptr;
}
return artObjAttributesManager_->getObjectCopyByHandle(fullArtObjName);
} // SceneDatasetAttributes::getNamedArticulatedObjectAttributesCopy

namespace {

std::string concatStrings(const std::string& header,
Expand Down
43 changes: 19 additions & 24 deletions src/esp/metadata/attributes/SceneDatasetAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,20 @@ class SceneDatasetAttributes : public AbstractAttributes {
attributes::ObjectAttributes::ptr getNamedObjectAttributesCopy(
const std::string& objAttrName);

/**
* @brief Returns articulated object attributes corresponding to passed handle
* as substring. Assumes articulated object attributes with @p artObjAttrName
* as substring exists in current dataset.
* @param artObjAttrName substring to handle of articulated object instance
* attributes that exists in current active dataset. The attributes will be
* found via substring search, so the name is expected to be sufficiently
* restrictive to have exactly 1 match in dataset.
* @return smart pointer to articulated object attributes if exists, nullptr
* otherwise.
*/
attributes::ArticulatedObjectAttributes::ptr
getNamedArticulatedObjectAttributesCopy(const std::string& artObjAttrName);

/**
* @brief Returns a lightsetup object configured by the attributes whose
* handle contains the passed @p lightSetupName
Expand All @@ -301,7 +315,7 @@ class SceneDatasetAttributes : public AbstractAttributes {
* or empty string if none.
*/
inline std::string getStageAttrFullHandle(const std::string& stageAttrName) {
return getFullAttrNameFromStr(stageAttrName, stageAttributesManager_);
return stageAttributesManager_->getFullAttrNameFromStr(stageAttrName);
} // getStageAttrFullHandle

/**
Expand All @@ -316,7 +330,7 @@ class SceneDatasetAttributes : public AbstractAttributes {
* empty string if none.
*/
inline std::string getObjAttrFullHandle(const std::string& objAttrName) {
return getFullAttrNameFromStr(objAttrName, objectAttributesManager_);
return objectAttributesManager_->getFullAttrNameFromStr(objAttrName);
} // getObjAttrFullHandle

/**
Expand All @@ -332,7 +346,7 @@ class SceneDatasetAttributes : public AbstractAttributes {
*/
inline std::string getArticulatedObjModelFullHandle(
const std::string& artObjModelName) {
return getFullAttrNameFromStr(artObjModelName, artObjAttributesManager_);
return artObjAttributesManager_->getFullAttrNameFromStr(artObjModelName);
// std::map<std::string, std::string> articulatedObjPaths;
}

Expand Down Expand Up @@ -362,8 +376,8 @@ class SceneDatasetAttributes : public AbstractAttributes {
(lightSetupName == NO_LIGHT_KEY)) {
return lightSetupName;
}
return getFullAttrNameFromStr(lightSetupName,
lightLayoutAttributesManager_);
return lightLayoutAttributesManager_->getFullAttrNameFromStr(
lightSetupName);
} // getLightSetupFullHandle

/**
Expand Down Expand Up @@ -391,25 +405,6 @@ class SceneDatasetAttributes : public AbstractAttributes {
*/
std::string getObjectInfoInternal() const override;

/**
* @brief Returns actual attributes handle containing @p attrName as a
* substring, or the empty string if none exists, from passed @p attrMgr .
* Does a substring search, and returns first value found.
* @param attrName name to be used as searching substring in @p attrMgr .
* @param attrMgr attributes manager to be searched
* @return actual name of attributes in attrMgr, or empty string if does not
* exist.
*/
inline std::string getFullAttrNameFromStr(
const std::string& attrName,
const ManagedContainerBase::ptr& attrMgr) {
auto handleList = attrMgr->getObjectHandlesBySubstring(attrName);
if (!handleList.empty()) {
return handleList[0];
}
return "";
} // getFullAttrNameFromStr

/**
* @brief This will add a navmesh entry or a semantic scene descriptor entry
* to the appropriate map. It checks if a value already exists at the
Expand Down
19 changes: 19 additions & 0 deletions src/esp/metadata/managers/AttributesManagerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,25 @@ class AttributesManager : public ManagedFileBasedContainer<T, Access> {
const attributes::AbstractAttributes::ptr& attribs,
const io::JsonGenericValue& jsonConfig) const;

/**
* @brief Returns actual attributes handle containing @p attrName as a
* substring, or the empty string if none exists.
* Does a substring search, and returns first value found.
* @param attrName name to be used as searching substring in @p attrMgr
* @return actual name of attributes in attrMgr, or empty string if does not
* exist.
*/
inline std::string getFullAttrNameFromStr(const std::string& attrName) {
if (this->getObjectLibHasHandle(attrName)) {
return attrName;
}
auto handleList = this->getObjectHandlesBySubstring(attrName);
if (!handleList.empty()) {
return handleList[0];
}
return "";
} // getFullAttrNameFromStr

protected:
/**
* @brief Called intenrally from createObject. This will create either a
Expand Down
1 change: 0 additions & 1 deletion src/esp/metadata/managers/ObjectAttributesManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ ObjectAttributesManager::createPrimBasedAttributesTemplate(
} // ObjectAttributesManager::createPrimBasedAttributesTemplate

void ObjectAttributesManager::createDefaultPrimBasedAttributesTemplates() {
this->undeletableObjectNames_.clear();
// build default primtive object templates corresponding to given default
// asset templates
std::vector<std::string> lib =
Expand Down
2 changes: 1 addition & 1 deletion src/utils/viewer/viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ Viewer::Viewer(const Arguments& arguments)
if (!font_ || !font_->openData(rs.getRaw("ProggyClean.ttf"), fontSize))
Mn::Fatal{} << "Cannot open font file";

fontGlyphCache_.emplace(Mn::Vector2i{256});
fontGlyphCache_.emplace(Mn::Vector2i{256}, Mn::Vector2i{1});
/* Don't destroy the bitmap font with smooth scaling */
fontGlyphCache_->texture().setMagnificationFilter(
Mn::SamplerFilter::Nearest);
Expand Down

0 comments on commit d46492a

Please sign in to comment.