diff --git a/Changes b/Changes index 98c5ce5d72..0262cd8aa4 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,13 @@ 10.5.x.x (relative to 10.5.1.0) ======== +Breaking Changes +---------------- +- IECoreMaya : Maya meshes converted from Cortex data no longer have normals set explicitly and instead relies on Maya to calculate them. + +Fixes +--- +- ToMayaMeshConverter : No longer locks normals set on the Mesh from the scc. 10.5.1.0 (relative to 10.5.0.0) ======== diff --git a/src/IECoreMaya/ToMayaMeshConverter.cpp b/src/IECoreMaya/ToMayaMeshConverter.cpp index 39fb938e4c..cf31c75187 100644 --- a/src/IECoreMaya/ToMayaMeshConverter.cpp +++ b/src/IECoreMaya/ToMayaMeshConverter.cpp @@ -183,6 +183,10 @@ void ToMayaMeshConverter::addUVSet( MFnMesh &fnMesh, const MIntArray &polygonCou bool ToMayaMeshConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const { + // Note: Normals are not set on the Mesh from the scc as by setting them + // explicitly we are implying they should be locked which is not + // supported, instead we rely on Maya computing the normals everytime + MStatus s; IECoreScene::ConstMeshPrimitivePtr mesh = IECore::runTimeCast( from ); @@ -263,79 +267,6 @@ bool ToMayaMeshConverter::doConversion( IECore::ConstObjectPtr from, MObject &to return false; } - it = mesh->variables.find("N"); - if ( it != mesh->variables.end() ) - { - if (it->second.interpolation == IECoreScene::PrimitiveVariable::FaceVarying ) - { - /// \todo Employ some M*Array converters to simplify this - MVectorArray vertexNormalsArray; - IECore::ConstV3fVectorDataPtr n = IECore::runTimeCast(it->second.data); - if (n) - { - IECoreScene::PrimitiveVariable::IndexedView normalView = IECoreScene::PrimitiveVariable::IndexedView( it->second ); - vertexNormalsArray.setLength( normalView.size() ); - - size_t i = 0; - for(const auto& normal : normalView) - { - vertexNormalsArray[i++] = IECore::convert( normal ); - } - } - else - { - IECore::ConstV3dVectorDataPtr n = IECore::runTimeCast(it->second.data); - if (n) - { - IECoreScene::PrimitiveVariable::IndexedView normalView = IECoreScene::PrimitiveVariable::IndexedView( it->second ); - vertexNormalsArray.setLength( normalView.size() ); - - size_t i = 0; - for(const auto& normal : normalView) - { - vertexNormalsArray[i++] = IECore::convert( normal ); - } - } - else - { - IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"N\" has unsupported type \"%s\"." ) % it->second.data->typeName() ); - } - } - - if ( vertexNormalsArray.length() ) - { - MStatus status; - MItMeshPolygon itPolygon( mObj, &status ); - if( status != MS::kSuccess ) - { - IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to create mesh iterator" ); - } - - unsigned v = 0; - MIntArray vertexIds; - MIntArray faceIds; - - for ( ; !itPolygon.isDone(); itPolygon.next() ) - { - for ( v=0; v < itPolygon.polygonVertexCount(); ++v ) - { - faceIds.append( itPolygon.index() ); - vertexIds.append( itPolygon.vertexIndex( v ) ); - } - } - - if( !fnMesh.setFaceVertexNormals( vertexNormalsArray, faceIds, vertexIds ) ) - { - IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Setting normals failed" ); - } - } - } - else - { - IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "PrimitiveVariable \"N\" has unsupported interpolation (expected FaceVarying)." ); - } - } - /// Add UV sets for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it ) { diff --git a/test/IECoreMaya/ParameterisedHolder.py b/test/IECoreMaya/ParameterisedHolder.py index c40c4579b8..7fd5b4066e 100644 --- a/test/IECoreMaya/ParameterisedHolder.py +++ b/test/IECoreMaya/ParameterisedHolder.py @@ -286,7 +286,6 @@ def testMeshParameterIOProblem( self ) : op = fnOP.getOp() mesh = IECoreScene.MeshPrimitive.createBox( imath.Box3f( imath.V3f( -2, -2, -2 ), imath.V3f( 2, 3, 4 ) ) ) - mesh[ "N" ] = IECoreScene.PrimitiveVariable( mesh[ "N" ].interpolation, mesh[ "N" ].expandedData() ) op.parameters()[ "input" ].setValue( mesh ) fnOP.setNodeValues() @@ -301,7 +300,13 @@ def testMeshParameterIOProblem( self ) : op = fnOP.getOp() mesh2 = op.parameters()["input"].getValue() + self.assertTrue( mesh2.arePrimitiveVariablesValid() ) + # The ToMayaMeshConverter relies on Maya to calculate the normals + # whereas createBox uses indexed normals so we cannot include them + # in the comparison otherwise they will never be the same + del mesh[ "N" ] + del mesh2[ "N" ] self.assertEqual( mesh2, mesh ) def testOpHolder( self ) : diff --git a/test/IECoreMaya/ToMayaMeshConverterTest.py b/test/IECoreMaya/ToMayaMeshConverterTest.py index 245b1f189c..cfb813b217 100644 --- a/test/IECoreMaya/ToMayaMeshConverterTest.py +++ b/test/IECoreMaya/ToMayaMeshConverterTest.py @@ -308,6 +308,9 @@ def testNormals( self ) : self.assertAlmostEqual( origNormal[j], normal3f[j], 6 ) self.assertAlmostEqual( origNormal[j], normal3d[j], 6 ) + # normals should always be unlocked when reading from scc + self.assertFalse( any( maya.cmds.polyNormalPerVertex( newSphere+".vtx[*]", query=True, allLocked=True ) ) ) + def testSetMeshInterpolation( self ) : sphere = maya.cmds.polySphere( subdivisionsX=10, subdivisionsY=5, constructionHistory=False )