Skip to content

Commit d7949ec

Browse files
committed
Merge branch 'RB-10.4' into main
2 parents c928280 + 5d4466b commit d7949ec

File tree

16 files changed

+371
-57
lines changed

16 files changed

+371
-57
lines changed

Changes

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
10.4.1.1 (relative to 10.4.1.0)
2+
========
3+
4+
Fixes
5+
-----
6+
7+
- AlembicScene : Fixed hash for animated visibility attribute (#1295).
8+
- Font : Fixed crashes caused by negative `char` values (#1291).
9+
- IECoreMaya : Fixed erroneous display of hidden locations in VP2 (#1290).
10+
- IECoreMaya : Updated SceneShape drawing to respect ancestral visibility overrides (#1290).
11+
- IECoreMaya : Fixed SceneShape isolate selection in maya (#1290).
12+
- USDScene : Fixed loading of primitive variables from UsdGeomPointInstancers (#1292).
13+
114
10.4.1.0 (relative to 10.4.0.0)
215
========
316

@@ -60,6 +73,17 @@ Build
6073

6174
- Updated IE options file to support Nuke 13.x custom dependencies (#1263).
6275

76+
10.3.7.2 (relative to 10.3.7.1)
77+
========
78+
79+
Fixes
80+
-----
81+
82+
- IECoreMaya : Fixed erroneous display of hidden locations in VP2 (#1290).
83+
- IECoreMaya : Updated SceneShape drawing to respect ancestral visibility overrides (#1290).
84+
- IECoreMaya : Fixed SceneShape isolate selection in maya (#1290).
85+
- USDScene : Fixed loading of primitive variables from UsdGeomPointInstancers (#1292).
86+
6387
10.3.7.1 (relative to 10.3.7.0)
6488
========
6589

SConstruct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ SConsignFile()
5757
ieCoreMilestoneVersion = 10 # for announcing major milestones - may contain all of the below
5858
ieCoreMajorVersion = 4 # backwards-incompatible changes
5959
ieCoreMinorVersion = 1 # new backwards-compatible features
60-
ieCorePatchVersion = 0 # bug fixes
60+
ieCorePatchVersion = 1 # bug fixes
6161
ieCoreVersionSuffix = "" # used for alpha/beta releases. Example: "a1", "b2", etc.
6262

6363
###########################################################################################

contrib/IECoreAlembic/src/IECoreAlembic/AlembicScene.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,26 @@ class AlembicScene::AlembicReader : public AlembicIO
850850
const IXformSchema &schema = m_xform.getSchema();
851851
ICompoundProperty compoundProperty = schema.getUserProperties();
852852

853+
bool haveAttributes = false;
854+
bool haveAnimation = false;
855+
853856
if( compoundProperty.valid() )
857+
{
858+
haveAttributes = true;
859+
haveAnimation = haveAnimation || isAnimated( compoundProperty );
860+
}
861+
862+
if( auto visibilityReader = scalarPropertyReader( visibilityName ) )
863+
{
864+
haveAttributes = true;
865+
haveAnimation = haveAnimation || !visibilityReader->isConstant();
866+
}
867+
868+
if( haveAttributes )
854869
{
855870
h.append( fileName() );
856871
h.append( m_xform ? m_xform.getFullName() : "/" );
857-
858-
if( isAnimated( compoundProperty ) )
872+
if( haveAnimation )
859873
{
860874
h.append( time );
861875
}

contrib/IECoreAlembic/test/IECoreAlembic/AlembicSceneTest.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,24 +1964,46 @@ def testVisibilityAttribute( self ) :
19641964

19651965
fileName = os.path.join( self.temporaryDirectory(), "visibilityAttribute.abc" )
19661966
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )
1967+
19671968
root.createChild( "withoutAttribute" )
1968-
child = root.createChild( "withAttribute" )
1969+
1970+
child = root.createChild( "withAnimatedAttribute" )
19691971
child.writeAttribute( "scene:visible", IECore.BoolData( True ), 0 )
19701972
child.writeAttribute( "scene:visible", IECore.BoolData( False ), 1 )
19711973

1974+
child = root.createChild( "withStaticAttribute" )
1975+
child.writeAttribute( "scene:visible", IECore.BoolData( True ), 0 )
1976+
19721977
del child, root
19731978

19741979
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
19751980

1976-
child = root.child( "withAttribute" )
1981+
child = root.child( "withoutAttribute" )
1982+
self.assertNotIn( "scene:visible", child.attributeNames() )
1983+
self.assertFalse( child.hasAttribute( "scene:visible" ) )
1984+
withoutHash = child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 0 )
1985+
1986+
child = root.child( "withAnimatedAttribute" )
19771987
self.assertIn( "scene:visible", child.attributeNames() )
19781988
self.assertTrue( child.hasAttribute( "scene:visible" ) )
19791989
self.assertEqual( child.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
19801990
self.assertEqual( child.readAttribute( "scene:visible", 1 ), IECore.BoolData( False ) )
1991+
animatedFrame1Hash = child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 1 )
1992+
self.assertNotEqual( child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 0 ), animatedFrame1Hash )
1993+
self.assertNotEqual( child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 0 ), withoutHash )
1994+
self.assertNotEqual( animatedFrame1Hash, withoutHash )
19811995

1982-
child = root.child( "withoutAttribute" )
1983-
self.assertNotIn( "scene:visible", child.attributeNames() )
1984-
self.assertFalse( child.hasAttribute( "scene:visible" ) )
1996+
child = root.child( "withStaticAttribute" )
1997+
self.assertIn( "scene:visible", child.attributeNames() )
1998+
self.assertTrue( child.hasAttribute( "scene:visible" ) )
1999+
self.assertEqual( child.readAttribute( "scene:visible", 0 ), IECore.BoolData( True ) )
2000+
self.assertEqual( child.readAttribute( "scene:visible", 1 ), IECore.BoolData( True ) )
2001+
self.assertEqual(
2002+
child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 0 ),
2003+
child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 1 ),
2004+
)
2005+
self.assertNotEqual( child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 1 ), animatedFrame1Hash )
2006+
self.assertNotEqual( child.hash( IECoreScene.SceneInterface.HashType.AttributesHash, 1 ), withoutHash )
19852007

19862008
if __name__ == "__main__":
19872009
unittest.main()

contrib/IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ IECore::ObjectPtr readPointInstancer( pxr::UsdGeomPointInstancer &pointInstancer
123123

124124
newPoints->variables["prototypeRoots"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Constant, prototypeRootsData );
125125

126+
// Primitive variables
127+
128+
PrimitiveAlgo::readPrimitiveVariables( pxr::UsdGeomPrimvarsAPI( pointInstancer ), time, newPoints.get(), canceller );
129+
126130
return newPoints;
127131
}
128132

@@ -136,7 +140,10 @@ bool pointInstancerMightBeTimeVarying( pxr::UsdGeomPointInstancer &instancer )
136140
instancer.GetScalesAttr().ValueMightBeTimeVarying() ||
137141
instancer.GetVelocitiesAttr().ValueMightBeTimeVarying() ||
138142
instancer.GetAccelerationsAttr().ValueMightBeTimeVarying() ||
139-
instancer.GetAngularVelocitiesAttr().ValueMightBeTimeVarying()
143+
instancer.GetAngularVelocitiesAttr().ValueMightBeTimeVarying() ||
144+
PrimitiveAlgo::primitiveVariablesMightBeTimeVarying(
145+
pxr::UsdGeomPrimvarsAPI( instancer )
146+
)
140147
;
141148
}
142149

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,5 +3240,36 @@ def testMultipleLights( self ) :
32403240
self.assertIsInstance( attribute, IECoreScene.ShaderNetwork )
32413241
self.assertEqual( attribute.outputShader().parameters["exposure"], IECore.FloatData( exposure ) )
32423242

3243+
def testPointInstancerPrimvars( self ) :
3244+
3245+
# Use the USD API to author a point instancer with primvars on it.
3246+
3247+
fileName = os.path.join( self.temporaryDirectory(), "pointInstancePrimvars.usda" )
3248+
stage = pxr.Usd.Stage.CreateNew( fileName )
3249+
points = pxr.UsdGeom.PointInstancer.Define( stage, "/points" )
3250+
points.CreatePositionsAttr( [ ( v, v, v ) for v in range( 0, 5 ) ] )
3251+
3252+
primvars = pxr.UsdGeom.PrimvarsAPI( points )
3253+
primvar = primvars.CreatePrimvar( "myColor", pxr.Sdf.ValueTypeNames.Color3fArray, "vertex" )
3254+
primvar.Set(
3255+
[ ( c, c, c ) for c in range( 1, 6 ) ]
3256+
)
3257+
3258+
stage.GetRootLayer().Save()
3259+
3260+
# Check we can load the primvar via a SceneInterface.
3261+
3262+
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
3263+
points = root.child( "points" ).readObject( 0 )
3264+
3265+
self.assertIsInstance( points, IECoreScene.PointsPrimitive )
3266+
self.assertIn( "myColor", points )
3267+
self.assertEqual(
3268+
points["myColor"].data,
3269+
IECore.Color3fVectorData( [ imath.Color3f( c ) for c in range( 1, 6 ) ] )
3270+
)
3271+
self.assertEqual( points["myColor"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex )
3272+
self.assertEqual( points["myColor"].indices, None )
3273+
32433274
if __name__ == "__main__":
32443275
unittest.main()

include/IECoreMaya/LiveScene.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ class IECOREMAYA_API LiveScene : public IECoreScene::SceneInterface
7878
/// Name of maya attribute overriding `IECoreScene::SceneInterface::visibilityName`
7979
static IECoreScene::SceneInterface::Name visibilityOverrideName;
8080

81-
/// Returns the MDagPath object to the scene node
82-
MDagPath dagPath() const;
83-
8481
/*
8582
* Bounding box
8683
*/
@@ -188,6 +185,19 @@ class IECOREMAYA_API LiveScene : public IECoreScene::SceneInterface
188185
/// Currently raises an exception
189186
void hash( HashType hashType, double time, IECore::MurmurHash &h ) const override;
190187

188+
/*
189+
* Utility functions
190+
*/
191+
192+
/// Returns the MDagPath object to the scene node
193+
MDagPath dagPath() const;
194+
195+
/// Returns the scene path corresponding to the maya dag path
196+
static void dagPathToPath( MDagPath dagPath, IECoreScene::SceneInterface::Path &path );
197+
198+
/// Returns the maya dag path corresponding to the scene path
199+
static void pathToDagPath( const IECoreScene::SceneInterface::Path &path, MDagPath &dagPath );
200+
191201
/// Translates cortex attribute name to maya attribute name
192202
/// Returns an empty string if there are no valid mappings
193203
static Name toMayaAttributeName( const Name &name );

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/LiveScene.cpp

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,20 +206,7 @@ void LiveScene::path( Path &p ) const
206206
throw Exception( "IECoreMaya::LiveScene::path: Dag path no longer exists!" );
207207
}
208208

209-
std::string pathStr( m_dagPath.fullPathName().asChar() );
210-
boost::tokenizer<boost::char_separator<char> > t( pathStr, boost::char_separator<char>( "|" ) );
211-
212-
p.clear();
213-
214-
for (
215-
boost::tokenizer<boost::char_separator<char> >::iterator it = t.begin();
216-
it != t.end();
217-
++it
218-
)
219-
{
220-
p.push_back( Name( *it ) );
221-
}
222-
209+
dagPathToPath( m_dagPath, p );
223210
}
224211

225212
Imath::Box3d LiveScene::readBound( double time ) const
@@ -1122,6 +1109,66 @@ void LiveScene::hash( HashType hashType, double time, MurmurHash &h ) const
11221109
throw Exception( "Hashes currently not supported in IECoreMaya::LiveScene objects." );
11231110
}
11241111

1112+
void LiveScene::dagPathToPath( MDagPath dagPath, IECoreScene::SceneInterface::Path &path )
1113+
{
1114+
tbb::recursive_mutex::scoped_lock l( g_mutex );
1115+
path.clear();
1116+
1117+
if( dagPath.isValid() )
1118+
{
1119+
// Only transforms can be part of the path
1120+
if( !dagPath.hasFn( MFn::kTransform ) )
1121+
{
1122+
dagPath.pop();
1123+
}
1124+
1125+
const std::string pathStr( dagPath.fullPathName().asChar() );
1126+
const boost::tokenizer< boost::char_separator<char> > tokens( pathStr, boost::char_separator<char>( "|" ) );
1127+
for ( const auto &token : tokens )
1128+
{
1129+
path.push_back( token );
1130+
}
1131+
1132+
return;
1133+
}
1134+
1135+
throw Exception( "IECoreMaya::LiveScene::dagPathToPath invalid dag path." );
1136+
}
1137+
1138+
void LiveScene::pathToDagPath( const IECoreScene::SceneInterface::Path &path, MDagPath &dagPath )
1139+
{
1140+
tbb::recursive_mutex::scoped_lock l( g_mutex );
1141+
1142+
if( path.empty() )
1143+
{
1144+
MItDag itDag;
1145+
itDag.getPath( dagPath );
1146+
return;
1147+
}
1148+
1149+
std::string dagPathStr;
1150+
for( const auto &name : path )
1151+
{
1152+
dagPathStr += "|";
1153+
dagPathStr += name;
1154+
}
1155+
1156+
MSelectionList sel;
1157+
if( sel.add( dagPathStr.c_str() ) && sel.getDagPath( 0, dagPath ) )
1158+
{
1159+
return;
1160+
}
1161+
1162+
// Invalid dag path
1163+
std::string pathStr;
1164+
IECoreScene::SceneInterface::pathToString( path, pathStr );
1165+
throw Exception(
1166+
boost::str(
1167+
boost::format( "IECoreMaya::LiveScene::pathToDagPath invalid conversion to dag path from \"%1%\"." ) % pathStr
1168+
)
1169+
);
1170+
}
1171+
11251172
void LiveScene::registerCustomObject( HasFn hasFn, ReadFn readFn )
11261173
{
11271174
CustomReader r;

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 ) );

0 commit comments

Comments
 (0)