Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*.lib
*.ilk
*.exp
.sconsign.dblite
.sconsign*.dblite
.sconf_temp
.cproject
.project
Expand Down
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Fixes
- USDScene :
- Fixed round-tripping of colons in set names.
- Fixed `hash()` to consider animation on ModelAPI extents when hashing the bound.
- ToMayaMeshConverter : Reverted #1386 that no longer locked normals set on the Mesh from the scc to fix issues with Maya incorrectly recomputing normals as Vertex normals when they were originally computed as Face normals

10.5.9.1 (relative to 10.5.9.0)
========
Expand Down
77 changes: 73 additions & 4 deletions src/IECoreMaya/ToMayaMeshConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,6 @@ 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<const IECoreScene::MeshPrimitive>( from );
Expand Down Expand Up @@ -267,6 +263,79 @@ 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<const IECore::V3fVectorData>(it->second.data);
if (n)
{
IECoreScene::PrimitiveVariable::IndexedView<Imath::V3f> normalView = IECoreScene::PrimitiveVariable::IndexedView<Imath::V3f>( it->second );
vertexNormalsArray.setLength( normalView.size() );

size_t i = 0;
for(const auto& normal : normalView)
{
vertexNormalsArray[i++] = IECore::convert<MVector, Imath::V3f>( normal );
}
}
else
{
IECore::ConstV3dVectorDataPtr n = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data);
if (n)
{
IECoreScene::PrimitiveVariable::IndexedView<Imath::V3d> normalView = IECoreScene::PrimitiveVariable::IndexedView<Imath::V3d>( it->second );
vertexNormalsArray.setLength( normalView.size() );

size_t i = 0;
for(const auto& normal : normalView)
{
vertexNormalsArray[i++] = IECore::convert<MVector, Imath::V3d>( 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 )
{
Expand Down
7 changes: 1 addition & 6 deletions test/IECoreMaya/ParameterisedHolder.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ 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()

Expand All @@ -300,13 +301,7 @@ 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 ) :
Expand Down
3 changes: 0 additions & 3 deletions test/IECoreMaya/ToMayaMeshConverterTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,6 @@ 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 )
Expand Down