-
Notifications
You must be signed in to change notification settings - Fork 202
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
MAYA-105827 - Compute extents for modified GPrims #1112
Changes from all commits
5b7b721
6d0cb0b
1faa083
736a05e
ae0614d
ef723c1
1926b67
825eff6
00e7118
923d5b6
2a63785
0eaf65b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,13 +38,17 @@ | |
#include <pxr/base/tf/token.h> | ||
#include <pxr/base/trace/trace.h> | ||
#include <pxr/usd/ar/resolver.h> | ||
#include <pxr/usd/sdf/attributeSpec.h> | ||
#include <pxr/usd/sdf/layer.h> | ||
#include <pxr/usd/sdf/path.h> | ||
#include <pxr/usd/usd/editContext.h> | ||
#include <pxr/usd/usd/prim.h> | ||
#include <pxr/usd/usd/stage.h> | ||
#include <pxr/usd/usd/stageCacheContext.h> | ||
#include <pxr/usd/usd/timeCode.h> | ||
#include <pxr/usd/usdGeom/bboxCache.h> | ||
#include <pxr/usd/usdGeom/boundable.h> | ||
#include <pxr/usd/usdGeom/gprim.h> | ||
#include <pxr/usd/usdGeom/imageable.h> | ||
#include <pxr/usd/usdGeom/tokens.h> | ||
#include <pxr/usd/usdUtils/stageCache.h> | ||
|
@@ -74,6 +78,7 @@ | |
#include <maya/MPlug.h> | ||
#include <maya/MPlugArray.h> | ||
#include <maya/MPoint.h> | ||
#include <maya/MProfiler.h> | ||
#include <maya/MPxSurfaceShape.h> | ||
#include <maya/MSelectionMask.h> | ||
#include <maya/MStatus.h> | ||
|
@@ -134,6 +139,18 @@ MObject MayaUsdProxyShapeBase::outTimeAttr; | |
MObject MayaUsdProxyShapeBase::outStageDataAttr; | ||
MObject MayaUsdProxyShapeBase::outStageCacheIdAttr; | ||
|
||
namespace { | ||
//! Profiler category for proxy accessor events | ||
const int _shapeBaseProfilerCategory = MProfiler::addCategory( | ||
#if MAYA_API_VERSION >= 20190000 | ||
"ProxyShapeBase", | ||
"ProxyShapeBase events" | ||
#else | ||
"ProxyShapeBase" | ||
#endif | ||
); | ||
} // namespace | ||
|
||
/* static */ | ||
void* MayaUsdProxyShapeBase::creator() { return new MayaUsdProxyShapeBase(); } | ||
|
||
|
@@ -773,6 +790,9 @@ MBoundingBox MayaUsdProxyShapeBase::boundingBox() const | |
{ | ||
TRACE_FUNCTION(); | ||
|
||
MProfilingScope profilingScope( | ||
_shapeBaseProfilerCategory, MProfiler::kColorB_L1, "Get shape BoundingBox"); | ||
|
||
MStatus status; | ||
|
||
// Make sure outStage is up to date | ||
|
@@ -1186,7 +1206,73 @@ void MayaUsdProxyShapeBase::_OnStageContentsChanged(const UsdNotice::StageConten | |
|
||
void MayaUsdProxyShapeBase::_OnStageObjectsChanged(const UsdNotice::ObjectsChanged& notice) | ||
{ | ||
MProfilingScope profilingScope( | ||
_shapeBaseProfilerCategory, MProfiler::kColorB_L1, "Process USD objects changed"); | ||
|
||
ProxyAccessor::stageChanged(_usdAccessor, thisMObject(), notice); | ||
|
||
// Recompute the extents of any UsdGeomBoundable that has authored extents | ||
const auto& stage = notice.GetStage(); | ||
if (stage != getUsdStage()) { | ||
TF_CODING_ERROR("We shouldn't be receiving notification for other stages than one " | ||
"returned by stage provider"); | ||
return; | ||
} | ||
|
||
for (const auto& changedPath : notice.GetChangedInfoOnlyPaths()) { | ||
if (!changedPath.IsPrimPropertyPath()) { | ||
continue; | ||
} | ||
|
||
const TfToken& changedPropertyToken = changedPath.GetNameToken(); | ||
if (changedPropertyToken == UsdGeomTokens->extent) { | ||
continue; | ||
} | ||
|
||
SdfPath changedPrimPath = changedPath.GetPrimPath(); | ||
const UsdPrim& changedPrim = stage->GetPrimAtPath(changedPrimPath); | ||
UsdGeomBoundable boundableObj = UsdGeomBoundable(changedPrim); | ||
if (!boundableObj) { | ||
continue; | ||
} | ||
|
||
// If the attribute is not part of the primitive schema, it does not affect extents | ||
#if USD_VERSION_NUM > 2002 | ||
auto attrDefn | ||
= changedPrim.GetPrimDefinition().GetSchemaAttributeSpec(changedPropertyToken); | ||
#else | ||
auto attrDefn = PXR_NS::UsdSchemaRegistry::GetAttributeDefinition( | ||
changedPrim.GetTypeName(), changedPropertyToken); | ||
#endif | ||
if (!attrDefn) { | ||
continue; | ||
} | ||
|
||
// Ignore all attributes known to GPrim and its base classes as they | ||
// are guaranteed not to affect extents: | ||
static const std::unordered_set<TfToken, TfToken::HashFunctor> ignoredAttributes( | ||
UsdGeomGprim::GetSchemaAttributeNames(true).cbegin(), | ||
UsdGeomGprim::GetSchemaAttributeNames(true).cend()); | ||
if (ignoredAttributes.count(changedPropertyToken) > 0) { | ||
continue; | ||
} | ||
|
||
UsdAttribute extentsAttr = boundableObj.GetExtentAttr(); | ||
if (extentsAttr.GetNumTimeSamples() > 0) { | ||
TF_CODING_ERROR( | ||
"Can not fix animated extents of %s made dirty by a change on %s.", | ||
changedPrimPath.GetString().c_str(), | ||
changedPropertyToken.GetText()); | ||
continue; | ||
} | ||
if (extentsAttr && extentsAttr.HasValue()) { | ||
VtVec3fArray extent(2); | ||
if (UsdGeomBoundable::ComputeExtentFromPlugins( | ||
boundableObj, UsdTimeCode::Default(), &extent)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is another challenging place. What if the extent is animated? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I must say that reacting by notification is probably not appropriate. There is not enough context to know if the values is/was animated which forces writing a single non-animated extent value. This makes the extent completely wrong if another untouched parameter is kept animated (radius and length of a capsule, for example). There is also no information stored for Undo, and no mechanism to store the undo data of an animated extent (same issue appears in Ufe Undo handler for We could build a set of affected boundables and wait until the Compute function of the shape node is called. At this time we might have a better overall view of the state. We still end up with animation issues: we are expected to compute the extent at the current frame, but might be forced to recompute for the whole clip duration since we have absolutely no idea about the final animated state of the extent, and more specifically, which attributes affect the extent. |
||
extentsAttr.Set(extent); | ||
} | ||
} | ||
} | ||
} | ||
|
||
bool MayaUsdProxyShapeBase::closestPoint( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filters out the transform notifications when manipulating USD objects.