Skip to content

Commit 6eac287

Browse files
committed
Merge pull request #272 from davidsminor/mayaSceneVisibility
Maya scene visibility
2 parents b0d60cc + f634a2d commit 6eac287

File tree

3 files changed

+158
-6
lines changed

3 files changed

+158
-6
lines changed

src/IECoreMaya/MayaScene.cpp

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
#include "IECoreMaya/FromMayaDagNodeConverter.h"
1111
#include "IECoreMaya/FromMayaCameraConverter.h"
1212
#include "IECoreMaya/Convert.h"
13+
#include "IECoreMaya/SceneShape.h"
1314

1415
#include "maya/MFnDagNode.h"
1516
#include "maya/MFnTransform.h"
17+
#include "maya/MPxTransform.h"
18+
#include "maya/MPxSurfaceShape.h"
1619
#include "maya/MFnCamera.h"
1720
#include "maya/MFnMatrixData.h"
1821
#include "maya/MFnNumericData.h"
@@ -212,6 +215,12 @@ bool MayaScene::hasAttribute( const Name &name ) const
212215
{
213216
throw Exception( "MayaScene::hasAttribute: Dag path no longer exists!" );
214217
}
218+
219+
if( name == SceneInterface::visibilityName )
220+
{
221+
return true;
222+
}
223+
215224
std::vector< CustomAttributeReader > &attributeReaders = customAttributeReaders();
216225
for ( std::vector< CustomAttributeReader >::const_iterator it = attributeReaders.begin(); it != attributeReaders.end(); ++it )
217226
{
@@ -238,6 +247,7 @@ void MayaScene::attributeNames( NameList &attrs ) const
238247
}
239248

240249
attrs.clear();
250+
attrs.push_back( SceneInterface::visibilityName );
241251
for ( std::vector< CustomAttributeReader >::const_iterator it = customAttributeReaders().begin(); it != customAttributeReaders().end(); it++ )
242252
{
243253
it->m_names( m_dagPath, attrs );
@@ -250,11 +260,81 @@ ConstObjectPtr MayaScene::readAttribute( const Name &name, double time ) const
250260
{
251261
return 0;
252262
}
253-
263+
254264
if( m_dagPath.length() == 0 )
255265
{
256266
throw Exception( "MayaScene::readAttribute: Dag path no longer exists!" );
257267
}
268+
269+
tbb::mutex::scoped_lock l( s_mutex );
270+
if( name == SceneInterface::visibilityName )
271+
{
272+
bool visible = true;
273+
274+
MStatus st;
275+
MFnDagNode dagFn( m_dagPath );
276+
MPlug visibilityPlug = dagFn.findPlug( MPxTransform::visibility, &st );
277+
if( st )
278+
{
279+
visible = visibilityPlug.asBool();
280+
}
281+
282+
if( visible )
283+
{
284+
MDagPath childDag;
285+
286+
// find an object that's either a SceneShape, or has a cortex converter and check its visibility:
287+
unsigned int childCount = 0;
288+
m_dagPath.numberOfShapesDirectlyBelow(childCount);
289+
290+
for ( unsigned int c = 0; c < childCount; c++ )
291+
{
292+
MDagPath d = m_dagPath;
293+
if( d.extendToShapeDirectlyBelow( c ) )
294+
{
295+
MFnDagNode fnChildDag(d);
296+
if( fnChildDag.typeId() == SceneShape::id )
297+
{
298+
childDag = d;
299+
break;
300+
}
301+
302+
if ( fnChildDag.isIntermediateObject() )
303+
{
304+
continue;
305+
}
306+
307+
FromMayaShapeConverterPtr shapeConverter = FromMayaShapeConverter::create( d );
308+
if( shapeConverter )
309+
{
310+
childDag = d;
311+
break;
312+
}
313+
314+
FromMayaDagNodeConverterPtr dagConverter = FromMayaDagNodeConverter::create( d );
315+
if( dagConverter )
316+
{
317+
childDag = d;
318+
break;
319+
}
320+
}
321+
}
322+
323+
if( childDag.isValid() )
324+
{
325+
MFnDagNode dagFn( childDag );
326+
MPlug visibilityPlug = dagFn.findPlug( MPxSurfaceShape::visibility, &st );
327+
if( st )
328+
{
329+
visible = visibilityPlug.asBool();
330+
}
331+
}
332+
333+
}
334+
335+
return new BoolData( visible );
336+
}
337+
258338
std::vector< CustomAttributeReader > &attributeReaders = customAttributeReaders();
259339
for ( std::vector< CustomAttributeReader >::const_iterator it = attributeReaders.begin(); it != attributeReaders.end(); ++it )
260340
{

src/IECoreMaya/SceneShape.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,18 +279,21 @@ void SceneShape::sceneShapeAttributeNames( const MDagPath &p, SceneInterface::Na
279279
return;
280280
}
281281

282+
SceneInterface::NameList sceneAttrNames;
282283
ConstSceneInterfacePtr scene = sceneShape->getSceneInterface();
283284
if ( !scene )
284285
{
285286
return;
286287
}
287-
scene->attributeNames( attributeNames );
288+
scene->attributeNames( sceneAttrNames );
289+
attributeNames.insert( attributeNames.end(), sceneAttrNames.begin(), sceneAttrNames.end() );
288290

289291
MFnDagNode fnChildDag( dagPath );
290292
if( !fnChildDag.isIntermediateObject() && hasSceneShapeLink( p ) )
291293
{
292294
attributeNames.push_back( LinkedScene::linkAttribute );
293295
}
296+
294297
}
295298

296299
ConstObjectPtr SceneShape::readSceneShapeAttribute( const MDagPath &p, SceneInterface::Name attributeName )

test/IECoreMaya/MayaSceneTest.py

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ def testCustomTags( self ) :
595595
doTest = True
596596

597597
def hasMyTags( node, tag, tagFilter ) :
598-
"""'archivable' should be on all transforms and 'renderable' only at shape transforms."""
598+
#'archivable' should be on all transforms and 'renderable' only at shape transforms.
599599

600600
if not doTest:
601601
return False
@@ -621,7 +621,7 @@ def hasMyTags( node, tag, tagFilter ) :
621621
return dagPath.fullPathName().endswith("Shape")
622622

623623
def readMyTags( node, tagFilter ) :
624-
"""'archivable' should be on all transforms and 'renderable' only at shape transforms."""
624+
#'archivable' should be on all transforms and 'renderable' only at shape transforms.
625625

626626
if not doTest:
627627
return []
@@ -712,17 +712,86 @@ def readMyAttribute( node, attr ) :
712712
sphereScene = scene.child('pSphere')
713713
self.assertEqual( scene.attributeNames(), [] )
714714
self.assertEqual( scene.readAttribute("anyAttr", 0.0), None )
715-
self.assertEqual( transformScene.attributeNames(), [ IECore.InternedString("transformAttribute") ] )
715+
self.assertEqual( transformScene.attributeNames(), [ IECore.InternedString("scene:visible"), IECore.InternedString("transformAttribute") ] )
716716
self.assertEqual( transformScene.hasAttribute("shapeAttribute"), False )
717717
self.assertEqual( transformScene.readAttribute("shapeAttribute", 0.0), None )
718718
self.assertEqual( transformScene.readAttribute( "transformAttribute", 0.0), IECore.FloatData(5) )
719-
self.assertEqual( sphereScene.attributeNames(), [ IECore.InternedString('shapeAttribute') ] )
719+
self.assertEqual( sphereScene.attributeNames(), [ IECore.InternedString("scene:visible"), IECore.InternedString('shapeAttribute') ] )
720720
self.assertEqual( sphereScene.readAttribute( "shapeAttribute", 0.0), IECore.StringData("mesh") )
721721

722722
# Disable custom attribute functions so they don't mess with other tests
723723
doTest = False
724+
725+
def testSceneVisible( self ) :
726+
727+
maya.cmds.createNode( "transform", name = "t1" )
728+
maya.cmds.createNode( "transform", name = "t2" )
729+
730+
scene = IECoreMaya.MayaScene()
731+
t1 = scene.child( "t1" )
732+
t2 = scene.child( "t2" )
733+
734+
self.assertEqual( t1.attributeNames(), ["scene:visible"] )
735+
self.assertEqual( t2.attributeNames(), ["scene:visible"] )
736+
737+
self.assertEqual( t1.hasAttribute( "scene:visible" ), True )
738+
self.assertEqual( t2.hasAttribute( "scene:visible" ), True )
739+
740+
self.assertEqual( t1.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
741+
self.assertEqual( t2.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
742+
743+
# test visibility on transform:
744+
maya.cmds.setAttr( "t1.visibility", False )
745+
746+
self.assertEqual( t1.readAttribute( "scene:visible", 0 ), IECore.BoolData( False ) )
747+
self.assertEqual( t2.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
748+
749+
maya.cmds.setAttr( "t1.visibility", True )
750+
751+
# test visibility on shape. Add a mesh to the two transforms, along with an image plane to confuse it:
752+
maya.cmds.createNode( "mesh", name = "m1", parent="t1" )
753+
maya.cmds.createNode( "imagePlane", name = "i1", parent="t1" )
754+
755+
maya.cmds.createNode( "imagePlane", name = "i2", parent="t2" )
756+
maya.cmds.createNode( "mesh", name = "m2", parent="t2" )
757+
758+
maya.cmds.setAttr( "i1.visibility", False )
759+
maya.cmds.setAttr( "i2.visibility", False )
760+
761+
# these should both be visible, as cortex ignores image planes and the meshes are visible:
762+
self.assertEqual( t1.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
763+
self.assertEqual( t2.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
764+
765+
maya.cmds.setAttr( "m1.visibility", False )
766+
maya.cmds.setAttr( "m2.visibility", False )
767+
768+
# should both be invisible now, as we've hidden the meshes:
769+
self.assertEqual( t1.readAttribute( "scene:visible", 0 ), IECore.BoolData( False ) )
770+
self.assertEqual( t2.readAttribute( "scene:visible", 0 ), IECore.BoolData( False ) )
771+
772+
def testSceneShapeVisible( self ) :
773+
774+
# make sure we are at time 0
775+
maya.cmds.currentTime( "0sec" )
776+
scene = IECoreMaya.MayaScene()
777+
778+
envShape = str( IECoreMaya.FnSceneShape.create( "ieScene1" ).fullPathName() )
779+
envNode = 'ieScene1'
780+
781+
envScene = scene.child( envNode )
782+
self.failUnless( IECore.InternedString( "scene:visible" ) in envScene.attributeNames() )
783+
784+
maya.cmds.setAttr( envShape+'.file', 'test/IECore/data/sccFiles/animatedSpheres.scc',type='string' )
785+
self.failUnless( IECore.InternedString( "scene:visible" ) in envScene.attributeNames() )
724786

787+
maya.cmds.setAttr( "ieScene1.visibility", False )
788+
self.assertEqual( envScene.readAttribute( "scene:visible", 0 ), IECore.BoolData( False ) )
725789

790+
maya.cmds.setAttr( "ieScene1.visibility", True )
791+
self.assertEqual( envScene.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
726792

793+
maya.cmds.setAttr( envShape + ".visibility", False )
794+
self.assertEqual( envScene.readAttribute( "scene:visible", 0 ), IECore.BoolData( False ) )
795+
727796
if __name__ == "__main__":
728797
IECoreMaya.TestProgram( plugins = [ "ieCore" ] )

0 commit comments

Comments
 (0)