Skip to content

Commit 825ee18

Browse files
IECOreUSD : support subdiv options
1 parent 2206127 commit 825ee18

File tree

2 files changed

+122
-2
lines changed

2 files changed

+122
-2
lines changed

contrib/IECoreUSD/src/IECoreUSD/MeshAlgo.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,30 @@ IECore::ObjectPtr readMesh( pxr::UsdGeomMesh &mesh, pxr::UsdTimeCode time, const
7676

7777
if( subdivScheme == pxr::UsdGeomTokens->catmullClark )
7878
{
79-
newMesh->setInterpolation( "catmullClark" );
79+
newMesh->setInterpolation( IECoreScene::MeshPrimitive::interpolationCatmullClark.string() );
8080
}
81+
else if( subdivScheme == pxr::UsdGeomTokens->loop )
82+
{
83+
newMesh->setInterpolation( IECoreScene::MeshPrimitive::interpolationLoop.string() );
84+
}
85+
else
86+
{
87+
// For "none", we currently use the default value of "linear". It would probably be preferrable if
88+
// we used the name "none", since this is different from "bilinear", which would indicate that
89+
// subdivision is being requested, but without altering the shape of the limit surface.
90+
}
91+
92+
pxr::TfToken interpolateBoundary;
93+
mesh.GetInterpolateBoundaryAttr().Get( &interpolateBoundary, time );
94+
newMesh->setInterpolateBoundary( interpolateBoundary.GetString() );
95+
96+
pxr::TfToken faceVaryingLinearInterpolation;
97+
mesh.GetFaceVaryingLinearInterpolationAttr().Get( &faceVaryingLinearInterpolation, time );
98+
newMesh->setFaceVaryingLinearInterpolation( faceVaryingLinearInterpolation.GetString() );
99+
100+
pxr::TfToken triangleSubdivisionRule;
101+
mesh.GetTriangleSubdivisionRuleAttr().Get( &triangleSubdivisionRule, time );
102+
newMesh->setTriangleSubdivisionRule( triangleSubdivisionRule.GetString() );
81103

82104
// Corners
83105

@@ -170,15 +192,23 @@ bool writeMesh( const IECoreScene::MeshPrimitive *mesh, const pxr::UsdStagePtr &
170192

171193
// Interpolation
172194

173-
if( mesh->interpolation() == std::string( "catmullClark" ) )
195+
if( mesh->interpolation() == IECoreScene::MeshPrimitive::interpolationCatmullClark.string() )
174196
{
175197
usdMesh.CreateSubdivisionSchemeAttr().Set( pxr::UsdGeomTokens->catmullClark );
176198
}
199+
else if( mesh->interpolation() == IECoreScene::MeshPrimitive::interpolationLoop.string() )
200+
{
201+
usdMesh.CreateSubdivisionSchemeAttr().Set( pxr::UsdGeomTokens->loop );
202+
}
177203
else
178204
{
179205
usdMesh.CreateSubdivisionSchemeAttr().Set( pxr::UsdGeomTokens->none );
180206
}
181207

208+
usdMesh.CreateInterpolateBoundaryAttr().Set( pxr::TfToken( mesh->getInterpolateBoundary().string() ), time );
209+
usdMesh.CreateFaceVaryingLinearInterpolationAttr().Set( pxr::TfToken( mesh->getFaceVaryingLinearInterpolation().string() ), time );
210+
usdMesh.CreateTriangleSubdivisionRuleAttr().Set( pxr::TfToken( mesh->getTriangleSubdivisionRule().string() ), time );
211+
182212
// Corners
183213

184214
if( mesh->cornerIds()->readable().size() )

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,96 @@ def testCanWriteSubD( self ):
843843

844844
self.assertEqual(readChild.readObject( 0.0 ).interpolation, "catmullClark")
845845

846+
def testSubdOptions( self ) :
847+
848+
fileName = os.path.join( self.temporaryDirectory(), "test.usda" )
849+
resaveFileName = os.path.join( self.temporaryDirectory(), "resave.usda" )
850+
851+
# We need a list of all the values from USD we should support. There probably should be a
852+
# more direct way to get this, but I have already wasted far, far too much time trying to
853+
# understand which USD API to use.
854+
dummyStage = pxr.Usd.Stage.CreateInMemory()
855+
dummyMesh = pxr.UsdGeom.Mesh.Define( dummyStage, "/mesh" )
856+
allowedSubScheme = dummyMesh.GetSubdivisionSchemeAttr().GetMetadata( "allowedTokens" )
857+
allowedIB = dummyMesh.GetInterpolateBoundaryAttr().GetMetadata( "allowedTokens" )
858+
allowedFVLI = dummyMesh.GetFaceVaryingLinearInterpolationAttr().GetMetadata( "allowedTokens" )
859+
allowedTS = dummyMesh.GetTriangleSubdivisionRuleAttr().GetMetadata( "allowedTokens" )
860+
861+
del dummyMesh
862+
del dummyStage
863+
864+
for property, allowed in [
865+
( "subdivisionScheme", allowedSubScheme ),
866+
( "interpolateBoundary", allowedIB ),
867+
( "faceVaryingLinearInterpolation", allowedFVLI ),
868+
( "triangleSubdivisionRule", allowedTS ),
869+
870+
]:
871+
for value in allowed:
872+
873+
if property == "subdivisionScheme" and value == "bilinear":
874+
# We know we don't support this
875+
continue
876+
877+
stage = pxr.Usd.Stage.CreateNew( fileName )
878+
mesh = pxr.UsdGeom.Mesh.Define( stage, "/mesh" )
879+
if property == "subdivisionScheme":
880+
mesh.CreateSubdivisionSchemeAttr().Set( value )
881+
else:
882+
mesh.CreateSubdivisionSchemeAttr().Set( "catmullClark" )
883+
884+
if property == "interpolateBoundary":
885+
mesh.CreateInterpolateBoundaryAttr().Set( value, 0.0 )
886+
887+
if property == "faceVaryingLinearInterpolation":
888+
mesh.CreateFaceVaryingLinearInterpolationAttr().Set( value, 0.0 )
889+
890+
if property == "triangleSubdivisionRule":
891+
mesh.CreateTriangleSubdivisionRuleAttr().Set( value, 0.0 )
892+
893+
stage.GetRootLayer().Save()
894+
del stage
895+
896+
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
897+
898+
cortexMesh = root.child( "mesh" ).readObject( 0.0 )
899+
if property == "subdivisionScheme":
900+
if value == "none":
901+
self.assertEqual( cortexMesh.interpolation, "linear" )
902+
else:
903+
self.assertEqual( cortexMesh.interpolation, value )
904+
elif property == "interpolateBoundary":
905+
self.assertEqual( cortexMesh.getInterpolateBoundary(), value )
906+
elif property == "faceVaryingLinearInterpolation":
907+
self.assertEqual( cortexMesh.getFaceVaryingLinearInterpolation(), value )
908+
elif property == "triangleSubdivisionRule":
909+
self.assertEqual( cortexMesh.getTriangleSubdivisionRule(), value )
910+
911+
sceneWrite = IECoreScene.SceneInterface.create( resaveFileName, IECore.IndexedIO.OpenMode.Write )
912+
root = sceneWrite.createChild( "root" )
913+
child = root.createChild( "mesh" )
914+
915+
child.writeObject ( cortexMesh, 0.0 )
916+
917+
del child
918+
del root
919+
del sceneWrite
920+
921+
rereadFile = pxr.Usd.Stage.Open( resaveFileName )
922+
rereadMesh = pxr.UsdGeom.Mesh.Get( rereadFile, "/root/mesh" )
923+
924+
if property == "subdivisionScheme":
925+
self.assertEqual( rereadMesh.GetSubdivisionSchemeAttr().Get( 0.0 ), value )
926+
elif property == "interpolateBoundary":
927+
self.assertEqual( rereadMesh.GetInterpolateBoundaryAttr().Get( 0.0 ), value )
928+
elif property == "faceVaryingLinearInterpolation":
929+
self.assertEqual( rereadMesh.GetFaceVaryingLinearInterpolationAttr().Get( 0.0 ), value )
930+
elif property == "triangleSubdivisionRule":
931+
self.assertEqual( rereadMesh.GetTriangleSubdivisionRuleAttr().Get( 0.0 ), value )
932+
933+
del rereadMesh
934+
del rereadFile
935+
846936
def testCanWriteAnimatedPrimitiveVariable ( self ):
847937

848938
fileName = os.path.join( self.temporaryDirectory(), "usd_animated_primvar.usda" )

0 commit comments

Comments
 (0)