Skip to content

Commit

Permalink
Merge pull request #1430 from chrisc-lee/revertNotSetNormalsForMesh
Browse files Browse the repository at this point in the history
ToMayaMeshConverter: Revert "ToMayaMeshConverter : No longer set normals"
  • Loading branch information
ivanimanishi authored Aug 30, 2024
2 parents 0c12a73 + e1ee2c8 commit 341b3de
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 14 deletions.
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

0 comments on commit 341b3de

Please sign in to comment.