Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[al] Performance improvements when processing prim meta data #245

Merged
merged 4 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/usd/translators/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ list(APPEND DEPENDANT_LIBRARIES
usdSkel
usdUtils
vt
OpenMayaFX
${MAYA_LIBRARIES}
${LIBRARY_NAME}
mayaUsd_Schemas
Expand Down
2 changes: 1 addition & 1 deletion plugin/al/lib/AL_USDMaya/AL/usdmaya/Global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ static void postFileRead(void*)
auto stage = proxy->getUsdStage();
proxy->deserialiseTranslatorContext();
proxy->translatorManufacture().preparePythonTranslators(proxy->context());
proxy->findTaggedPrims();
proxy->findPrimsWithMetaData();
proxy->deserialiseTransformRefs();
}
unloadedProxies.clear();
Expand Down
81 changes: 55 additions & 26 deletions plugin/al/lib/AL_USDMaya/AL/usdmaya/SelectabilityDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,70 +21,89 @@ namespace usdmaya {
//----------------------------------------------------------------------------------------------------------------------
bool SelectabilityDB::isPathUnselectable(const SdfPath& path) const
{
for(SdfPath unselectablePath : m_unselectablePaths)
auto begin = m_unselectablePaths.begin();
auto end = m_unselectablePaths.end();
auto foundPathEntry = end;
auto root = SdfPath::AbsoluteRootPath();
auto temp(path);

while(temp != root)
{
if(path.HasPrefix(unselectablePath))
foundPathEntry = std::lower_bound(begin, foundPathEntry, temp);
if(foundPathEntry != end && temp == *foundPathEntry)
{
return true;
}
temp = temp.GetParentPath();
}

return false;
}

//----------------------------------------------------------------------------------------------------------------------
void SelectabilityDB::removePathsAsUnselectable(const SdfPathVector& paths)
{
bool needsSort = false;
for(SdfPath path : paths)
{
needsSort |= removeUnselectablePath(path);
removeUnselectablePath(path);
}

if(needsSort)
auto end = m_unselectablePaths.end();
auto start = m_unselectablePaths.begin();
for(SdfPath path : paths)
{
sort();
auto temp = std::lower_bound(start, end, path);
if(temp != end)
{
if(*temp == path)
{
temp = m_unselectablePaths.erase(temp);
}
start = temp;
}
}
}

//----------------------------------------------------------------------------------------------------------------------
void SelectabilityDB::removePathAsUnselectable(const SdfPath& path)
{
if(removeUnselectablePath(path))
{
sort();
}
removeUnselectablePath(path);
}

//----------------------------------------------------------------------------------------------------------------------
void SelectabilityDB::addPathsAsUnselectable(const SdfPathVector& paths)
{
bool needsSort = false;
for(SdfPath path : paths)
auto end = m_unselectablePaths.end();
auto start = m_unselectablePaths.begin();
for(auto iter = paths.begin(), last = paths.end(); iter != last; ++iter)
{
needsSort |= addUnselectablePath(path);
}
start = std::lower_bound(start, end, *iter);

if(needsSort)
{
sort();
// If we've hit the end, we can simply append the remaining elements in one go.
if(start == end)
{
m_unselectablePaths.insert(end, iter, last);
return;
}

if(*start != *iter)
{
m_unselectablePaths.insert(start, *iter);
}
}
}

//----------------------------------------------------------------------------------------------------------------------
void SelectabilityDB::addPathAsUnselectable(const SdfPath& path)
{
if(addUnselectablePath(path))
{
sort();
}
addUnselectablePath(path);
}

//----------------------------------------------------------------------------------------------------------------------
bool SelectabilityDB::removeUnselectablePath(const SdfPath& path)
{
auto foundPathEntry = std::find(m_unselectablePaths.begin(), m_unselectablePaths.end(), path);
if(foundPathEntry != m_unselectablePaths.end())
auto end = m_unselectablePaths.end();
auto foundPathEntry = std::lower_bound(m_unselectablePaths.begin(), end, path);
if(foundPathEntry != end && *foundPathEntry == path)
{
m_unselectablePaths.erase(foundPathEntry);
return true;
Expand All @@ -95,7 +114,17 @@ bool SelectabilityDB::removeUnselectablePath(const SdfPath& path)
//----------------------------------------------------------------------------------------------------------------------
bool SelectabilityDB::addUnselectablePath(const SdfPath& path)
{
if(!std::binary_search(m_unselectablePaths.begin(), m_unselectablePaths.end(), path))
auto end = m_unselectablePaths.end();
auto iter = std::lower_bound(m_unselectablePaths.begin(), end, path);
if(iter != end)
{
if(*iter != path)
{
m_unselectablePaths.insert(iter, path);
return true;
}
}
else
{
m_unselectablePaths.push_back(path);
return true;
Expand All @@ -106,4 +135,4 @@ bool SelectabilityDB::addUnselectablePath(const SdfPath& path)
//----------------------------------------------------------------------------------------------------------------------
} // usdmaya
} // AL
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
43 changes: 40 additions & 3 deletions plugin/al/lib/AL_USDMaya/AL/usdmaya/SelectabilityDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#pragma once

#include "AL/usdmaya/Api.h"
#include "AL/usdmaya/ForwardDeclares.h"

#include "pxr/pxr.h"
#include "pxr/usd/sdf/path.h"
Expand All @@ -28,23 +29,60 @@ namespace usdmaya {
///---------------------------------------------------------------------------------------------------------------------
/// \brief Logic that stores a sorted list of paths which represent Selectable points in the USD hierarchy
///---------------------------------------------------------------------------------------------------------------------
class SelectabilityDB {
class SelectabilityDB
{
// at little unpleasant design wise, however it means the proxy shape can directly modify the internal
// list of unselectable paths. I have looked at moving some of that logic into this class, however that would
// incur a performance penalty (lock & excluded prim processing can be done at the same time).
friend class nodes::ProxyShape;
public:

SelectabilityDB()
: m_unselectablePaths()
{
m_unselectablePaths.reserve(128);
}

///-------------------------------------------------------------------------------------------------------------------
/// \brief Determines this path is unselectable
/// \param path that you want to determine if it's unselectable
///-------------------------------------------------------------------------------------------------------------------
AL_USDMAYA_PUBLIC
bool isPathUnselectable(const SdfPath& path) const;

///-------------------------------------------------------------------------------------------------------------------
/// \brief Determines whether there is an internal entry for the path specified (and only this path!). If you wish
/// to determine selectability, call isPathUnselectable instead.
/// \param path the path to check to see if exists
/// \return true if the path is contained, false if not.
///-------------------------------------------------------------------------------------------------------------------
bool containsPath(const SdfPath& path) const
{
auto foundPathEntry = std::lower_bound(m_unselectablePaths.begin(), m_unselectablePaths.end(), path);
if(foundPathEntry != m_unselectablePaths.end() && path == *foundPathEntry)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit-pick: could just return the result of the boolean expression and avoid the conditional altogether.

return (foundPathEntry != m_unselectablePaths.end() && path == *foundPathEntry);

Fine as it is, of course.

{
return true;
}
return false;
}

///-------------------------------------------------------------------------------------------------------------------
/// \brief Adds a list of paths to the selectable list
/// \param paths which will be added as selectable. All children paths will be also unselectable
///-------------------------------------------------------------------------------------------------------------------
AL_USDMAYA_PUBLIC
void addPathsAsUnselectable(const SdfPathVector& paths);

///-------------------------------------------------------------------------------------------------------------------
/// \brief Sets a list of paths to the selectable list
/// \param paths which will be added as selectable. All children paths will be also unselectable
///-------------------------------------------------------------------------------------------------------------------
void setPathsAsUnselectable(const SdfPathVector& paths)
{
m_unselectablePaths = paths;
std::sort(m_unselectablePaths.begin(), m_unselectablePaths.end());
}

///-------------------------------------------------------------------------------------------------------------------
/// \brief Adds a path to the unselectable list
/// \param path which will be added as unselectable. All children paths will be also unselectable
Expand Down Expand Up @@ -73,7 +111,6 @@ class SelectabilityDB {
void removePathAsUnselectable(const SdfPath& path);

private:
inline void sort(){std::sort(m_unselectablePaths.begin(), m_unselectablePaths.end());}
bool addUnselectablePath(const SdfPath& path);
bool removeUnselectablePath(const SdfPath& path);

Expand All @@ -84,4 +121,4 @@ class SelectabilityDB {
//----------------------------------------------------------------------------------------------------------------------
} // usdmaya
} // AL
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,13 @@ MStatus TranslatePrim::redoIt()

TF_DEBUG(ALUSDMAYA_COMMANDS).Msg("TranslatePrim::redoIt\n");
m_proxy->translatePrimPathsIntoMaya(newImportPaths, m_teardownPaths, tp);


// construct locks and selectability for imported prims
if(m_proxy->isLockPrimFeatureActive())
{
m_proxy->removeMetaData(m_teardownPaths);
m_proxy->processChangedMetaData(SdfPathVector(), newImportPaths);
}

auto stage = m_proxy->usdStage();
auto manufacture = m_proxy->translatorManufacture();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void ProxyShapePostLoadProcess::createTranformChainsForSchemaPrims(
newpath = ptrNode->makeUsdTransformChain(usdPrim.GetParent(), modifier, nodes::ProxyShape::kRequired, &modifier2, 0, pushToPrim, readAnimatedValues);
}
}
objsToCreate.push_back(std::make_pair(newpath, usdPrim));
objsToCreate.emplace_back(newpath, usdPrim);
}
else
{
Expand Down
35 changes: 20 additions & 15 deletions plugin/al/lib/AL_USDMaya/AL/usdmaya/fileio/TransformIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ namespace fileio {


//----------------------------------------------------------------------------------------------------------------------
TransformIterator::TransformIterator(UsdStageRefPtr stage, const MDagPath& parentPath)
TransformIterator::TransformIterator(UsdStageRefPtr stage, const MDagPath& parentPath, bool stopOnInstance)
: m_primStack(),
m_stage(stage)
m_stage(stage),
m_stopOnInstance(stopOnInstance)
{
TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("TransformIterator::TransformIterator parent path: %s\n", parentPath.fullPathName().asChar());

Expand All @@ -50,9 +51,10 @@ TransformIterator::TransformIterator(UsdStageRefPtr stage, const MDagPath& paren
}

//----------------------------------------------------------------------------------------------------------------------
TransformIterator::TransformIterator(const UsdPrim& usdStartPrim, const MDagPath& mayaStartPath)
: m_primStack()
, m_stage(usdStartPrim.GetStage())
TransformIterator::TransformIterator(const UsdPrim& usdStartPrim, const MDagPath& mayaStartPath, bool stopOnInstance)
: m_primStack(),
m_stage(usdStartPrim.GetStage()),
m_stopOnInstance(stopOnInstance)
{
m_primStack.reserve(128);
m_primStack.push_back(StackRef(usdStartPrim));
Expand Down Expand Up @@ -94,15 +96,18 @@ bool TransformIterator::next()
do
{
StackRef& r = *(m_primStack.end() - 1);
if(r.m_prim.IsInstance())
if(r.m_prim.IsInstance() && !m_stopOnInstance)
{
UsdPrim master = r.m_prim.GetMaster();
m_primStack.push_back(StackRef(master));
m_visitedMasterPrimPaths.insert(master.GetPath());
StackRef& p = *(m_primStack.end() - 2);
StackRef& c = *(m_primStack.end() - 1);
c.m_object = p.m_object;
next();
if(!m_stopOnInstance)
{
UsdPrim master = r.m_prim.GetMaster();
m_primStack.push_back(StackRef(master));
m_visitedMasterPrimPaths.insert(master.GetPath());
StackRef& p = *(m_primStack.end() - 2);
StackRef& c = *(m_primStack.end() - 1);
c.m_object = p.m_object;
next();
}
return !done();
}
else
Expand All @@ -116,7 +121,7 @@ bool TransformIterator::next()

{
StackRef& b = *(m_primStack.end() - 1);
if(b.m_prim.IsInstance())
if(b.m_prim.IsInstance() && !m_stopOnInstance)
{
m_primStack.pop_back();
}
Expand Down Expand Up @@ -203,4 +208,4 @@ UsdPrim TransformIterator::parentPrim() const
} // fileio
} // usdmaya
} // AL
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class TransformIterator
/// \param stage the stage to iterate over
/// \param parentPath the DAG path of the proxy shape
AL_USDMAYA_PUBLIC
TransformIterator(UsdStageRefPtr stage, const MDagPath& parentPath = MDagPath());
TransformIterator(UsdStageRefPtr stage, const MDagPath& parentPath = MDagPath(), bool stopOnInstance = false);

/// \brief ctor. Initialises the iterator to the root of the stage
/// \param startPrim a prim in a stage where the iteration should start
/// \param startMayaPath the DAG path of the proxy shape
AL_USDMAYA_PUBLIC
TransformIterator(const UsdPrim& startPrim, const MDagPath& startMayaPath);
TransformIterator(const UsdPrim& startPrim, const MDagPath& startMayaPath, bool stopOnInstance = false);

/// \brief return true if the iteration is complete
/// \return true when the iteration is complete
Expand Down Expand Up @@ -129,13 +129,12 @@ class TransformIterator
std::vector<StackRef> m_primStack;
UsdStageRefPtr m_stage;
MDagPath m_parentPath;

TfHashSet<SdfPath, SdfPath::Hash> m_visitedMasterPrimPaths;
bool m_stopOnInstance;
};

//----------------------------------------------------------------------------------------------------------------------
} // fileio
} // usdmaya
} // AL
//----------------------------------------------------------------------------------------------------------------------

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class Scope;
/// AL_USDMaya transformation matrix implementantations
/// \ingroup nodes
//----------------------------------------------------------------------------------------------------------------------

class BasicTransformationMatrix
: public MPxTransformationMatrix
{
Expand Down Expand Up @@ -71,7 +70,7 @@ class BasicTransformationMatrix
/// \brief return the prim this transform matrix is attached to
/// \return the prim this transform matrix is controlling
inline const UsdPrim& prim() const
{ return m_prim; }
{ return m_prim; }

virtual void initialiseToPrim(bool readFromPrim = true, Scope* node = 0) {}

Expand Down
Loading