diff --git a/Changes b/Changes index 205782a227..62420464d6 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,12 @@ 10.7.x.x (relative to 10.7.3.0) ======== +Fixes +----- +- USD : + - Changed name of `ParticleField3DGaussianSplat` `radiance:sphericalHarmonicsCoefficients` primitive variables to end in `:$COEFFICIENT` instead of `[$COEFFICIENT]`. + - Changed Cortex type of `ParticleField3DGaussianSplat` `opacities` primitive variable to be `FloatVectorData` regardless of the incoming USD type (float or half). 10.7.3.0 (relative to 10.7.2.0) ======== diff --git a/contrib/IECoreUSD/src/IECoreUSD/GaussianSplatAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/GaussianSplatAlgo.cpp index 52c1917a34..1b95ea6d5a 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/GaussianSplatAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/GaussianSplatAlgo.cpp @@ -97,6 +97,19 @@ IECore::ObjectPtr readGaussianSplat( pxr::UsdVolParticleField3DGaussianSplat &sp pxr::UsdAttribute opacitiesAttr; splats.UsesFloatOpacities( &opacitiesAttr ); PrimitiveAlgo::readPrimitiveVariable( opacitiesAttr, time, newPoints.get(), "opacities" ); + if( auto opacitiesHalfData = newPoints->variableData( "opacities" ) ) + { + // Cortex has HalfVectorData which supports half opacities. For consistency with + // other attributes and downstream clients, we convert to float. + + const std::vector &opacitiesHalf = opacitiesHalfData->readable(); + + FloatVectorDataPtr opacitiesData = new FloatVectorData(); + opacitiesData->writable().insert( opacitiesData->writable().end(), opacitiesHalf.begin(), opacitiesHalf.end() ); + + PrimitiveVariable v = PrimitiveVariable( PrimitiveVariable::Interpolation::Vertex, opacitiesData ); + newPoints->variables["opacities"] = v; + } Canceller::check( canceller ); pxr::UsdAttribute degreeAttr = splats.GetRadianceSphericalHarmonicsDegreeAttr(); @@ -126,7 +139,7 @@ IECore::ObjectPtr readGaussianSplat( pxr::UsdVolParticleField3DGaussianSplat &sp coefficients[j] = allCoefficients[j * coefficientCount + i]; } - newPoints->variables[fmt::format( "radiance:sphericalHarmonicsCoefficients[{}]", i )] = PrimitiveVariable( PrimitiveVariable::Interpolation::Vertex, coefficientsData ); + newPoints->variables[fmt::format( "radiance:sphericalHarmonicsCoefficients:{}", i )] = PrimitiveVariable( PrimitiveVariable::Interpolation::Vertex, coefficientsData ); } } diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index 15713f38e1..1506d96fae 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -5175,7 +5175,7 @@ def testReadGaussianSplats( self ) : ( "P", IECore.V3fVectorData, IECore.GeometricData.Interpretation.Point, 4 ), ( "orientations", IECore.QuatfVectorData, None, 4 ), ( "scales", IECore.V3fVectorData, IECore.GeometricData.Interpretation.Numeric, 4 ), - ( "opacities", IECore.FloatVectorData if sceneFile == "gaussianSplatsFloat.usda" else IECore.HalfVectorData, None, 4 ), + ( "opacities", IECore.FloatVectorData, None, 4 ), ( "radiance:sphericalHarmonicsDegree", IECore.IntData, None, None ), ] : with self.subTest( variable = variable ) : @@ -5186,7 +5186,7 @@ def testReadGaussianSplats( self ) : self.assertEqual( len( splats[variable].data ), vectorLength ) for i in range( 0, 4 ) : # degree = 1, count = ( degree + 1 ) * ( degree + 1 ) - variable = "radiance:sphericalHarmonicsCoefficients[{}]".format( i ) + variable = "radiance:sphericalHarmonicsCoefficients:{}".format( i ) self.assertIsInstance( splats[variable].data, IECore.V3fVectorData ) self.assertEqual( splats[variable].data.getInterpretation(), IECore.GeometricData.Interpretation.None_ ) self.assertEqual( len( splats[variable].data ), 4 )