Skip to content

Commit df78cb8

Browse files
committed
IECoreMaya : Updated SceneShape drawing to respect ancestral visibilty.
There have been visibility discrepancies when a layout is collasped or expanded. When collasped, the drawing code is able to read visibility overrides and hide the appropriate sub-hierarchies. However, when the same layout is expanded the visibility was tested at each expanded location, and it failed to consider overrides which occured further up in the hierarchy. This commit solves this discrepancy by using LiveScene to determine if the sceneShape is should actually be invisible due to an override further up the hierarchy. SceneShape registers a custom readAttribute function with LiveScene, so LiveScene is able to correctly read the visibility overrides during its traversal. In regards to performance, when a SceneShape is fully expanded, and there is a deep hierarchy of visible transforms, this commit will slightly impact the frame rate since LiveScene will be performing extra work to ensure there are no visiblity overrides. Some of this overhead may be reduced through the use of an extra visiblity tracking cache, but there is also a price to pay for the extra message callbacks necessary to keep the cache synchronized. On a fully visible robot with ~2870 locations, the frame rate dropped ~1.2 fps. However, in practice at IE, this will not affect the performance of our animation rigs since all SceneShapes will be expanded to maya geometry. In this scenario, MDagPath::isVisible() will return False since the SceneShape will be set to an intermediate object, and the LiveScene code path will not be executed.
1 parent 07b40ee commit df78cb8

File tree

4 files changed

+45
-3
lines changed

4 files changed

+45
-3
lines changed

include/IECoreMaya/SceneShapeInterface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ class IECOREMAYA_API SceneShapeInterface: public MPxComponentShape
138138
const std::vector< IECore::InternedString > & componentNames() const;
139139
/// Return the value of the time plug for the SceneShape.
140140
double time() const;
141+
/// Determines scene visibility while accounting for ancestral visibility overrides
142+
static bool isVisible( const MDagPath &dagPath );
141143

142144
protected :
143145

src/IECoreMaya/SceneShapeInterface.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "IECoreMaya/ToMayaCurveConverter.h"
5858
#include "IECoreMaya/MayaTypeIds.h"
5959
#include "IECoreMaya/PostLoadCallback.h"
60+
#include "IECoreMaya/LiveScene.h"
6061

6162
#include "IECorePython/ScopedGILLock.h"
6263
#include "IECorePython/ScopedGILRelease.h"
@@ -97,6 +98,7 @@
9798
#include "maya/MFnGeometryData.h"
9899
#include "maya/MPlugArray.h"
99100
#include "maya/MFileIO.h"
101+
#include "maya/MAnimControl.h"
100102

101103
#if MAYA_API_VERSION >= 201600
102104

@@ -539,6 +541,38 @@ double SceneShapeInterface::time() const
539541
return time.as( MTime::kSeconds );
540542
}
541543

544+
bool SceneShapeInterface::isVisible( const MDagPath &dagPath )
545+
{
546+
// Let maya check for basic dag visibility
547+
// Maya handles hidden shapes, display layers, render layers, and intermediate objects
548+
if( !dagPath.isVisible() )
549+
{
550+
return false;
551+
}
552+
553+
// Check for ancestral visibility via LiveScene which accounts for visibility overrides which are not exposed to maya
554+
IECoreMaya::ConstLiveScenePtr liveScene = new IECoreMaya::LiveScene();
555+
const double currentTime = MAnimControl::currentTime().as( MTime::kSeconds );
556+
557+
SceneInterface::Path scenePath;
558+
IECoreMaya::LiveScene::dagPathToPath( dagPath, scenePath );
559+
const size_t pathLength = scenePath.size();
560+
for( size_t i = 0; i < pathLength; ++i )
561+
{
562+
ConstSceneInterfacePtr scene = liveScene->scene( scenePath );
563+
ConstBoolDataPtr liveSceneVisibility = runTimeCast<const BoolData>( scene->readAttribute( SceneInterface::visibilityName, currentTime ) );
564+
if( liveSceneVisibility && !liveSceneVisibility->readable() )
565+
{
566+
// Not visible due to a visibility override
567+
return false;
568+
}
569+
570+
scenePath.pop_back();
571+
}
572+
573+
return true;
574+
}
575+
542576
MBoundingBox SceneShapeInterface::boundingBox() const
543577
{
544578
MBoundingBox bound( MPoint( -1, -1, -1 ), MPoint( 1, 1, 1 ) );

src/IECoreMaya/SceneShapeSubSceneOverride.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,16 +1923,15 @@ void SceneShapeSubSceneOverride::collectInstances( Instances &instances ) const
19231923
MDagPathArray dagPaths;
19241924
dagNode.getAllPaths(dagPaths);
19251925
size_t numInstances = dagPaths.length();
1926-
19271926
instances.reserve( numInstances );
1927+
19281928
for( size_t pathIndex = 0; pathIndex < numInstances; ++pathIndex )
19291929
{
19301930
MDagPath& path = dagPaths[pathIndex];
19311931
MMatrix matrix = path.inclusiveMatrix();
19321932
bool pathSelected = isPathSelected( selectionList, path );
19331933
bool componentMode = componentsSelectable( path );
1934-
MFnDagNode nodeFn( path );
1935-
bool visible = path.isVisible();
1934+
bool visible = IECoreMaya::SceneShapeInterface::isVisible( path );
19361935

19371936
instances.emplace_back( matrix, pathSelected, componentMode, path, visible );
19381937
}

src/IECoreMaya/SceneShapeUI.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ void SceneShapeUI::getDrawRequests( const MDrawInfo &info, bool objectAndActiveO
102102
{
103103
return;
104104
}
105+
106+
// make sure we don't have an ancestral visibility override which makes us invisible
107+
if( !SceneShapeInterface::isVisible( info.multiPath() ) )
108+
{
109+
return;
110+
}
111+
105112
// the node we're meant to be drawing
106113
SceneShape *sceneShape = (SceneShape *)surfaceShape();
107114

0 commit comments

Comments
 (0)