From 1d18c93ded91d7d5e33f8e5519d5d094ee7942e2 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk Date: Fri, 24 Jul 2020 11:58:40 -0400 Subject: [PATCH 1/3] MAYA-105735 Clean up empty map1 texcoord If the imported USD mesh does not have a "map1" or a "st" texcoord stream, then we make sure to get rid of the default created map1 texcoord on the Maya side. --- lib/mayaUsd/fileio/utils/meshReadUtils.cpp | 36 +++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/mayaUsd/fileio/utils/meshReadUtils.cpp b/lib/mayaUsd/fileio/utils/meshReadUtils.cpp index a398f1e117..a9179228f3 100644 --- a/lib/mayaUsd/fileio/utils/meshReadUtils.cpp +++ b/lib/mayaUsd/fileio/utils/meshReadUtils.cpp @@ -58,6 +58,9 @@ TF_DEFINE_PUBLIC_TOKENS(UsdMayaMeshColorSetTokens, TF_DEFINE_PRIVATE_TOKENS( _meshTokens, + // Default UV set name in Maya + (map1) + // we capitalize this because it doesn't correspond to an actual attribute (USD_EmitNormals) @@ -181,7 +184,7 @@ namespace } bool - assignUVSetPrimvarToMesh(const UsdGeomPrimvar& primvar, MFnMesh& meshFn) + assignUVSetPrimvarToMesh(const UsdGeomPrimvar& primvar, MFnMesh& meshFn, bool hasDefaultUVSet) { const TfToken& primvarName = primvar.GetPrimvarName(); @@ -246,7 +249,14 @@ namespace if (primvarName == UsdUtilsGetPrimaryUVSetName()) { // We assume that the primary USD UV set maps to Maya's default 'map1' // set which always exists, so we shouldn't try to create it. - uvSetName = "map1"; + uvSetName = _meshTokens->map1.GetText(); + } else if (!hasDefaultUVSet) { + // If map1 still exists, we rename and re-use it: + MStringArray uvSetNames; + meshFn.getUVSetNames(uvSetNames); + if (uvSetNames[0] == _meshTokens->map1.GetText()) { + meshFn.renameUVSet(_meshTokens->map1.GetText(), uvSetName); + } } else { status = meshFn.createUVSet(uvSetName); if (status != MS::kSuccess) { @@ -608,7 +618,25 @@ UsdMayaMeshReadUtils::assignPrimvarsToMesh(const UsdGeomMesh& mesh, // GETTING PRIMVARS const std::vector primvars = mesh.GetPrimvars(); - TF_FOR_ALL(iter, primvars) + + // Maya always has a map1 UV set. We need to find out if there is any stream in the file that + // will use that slot. If not, the first texcoord stream to load will replace the default map1 + // stream. + bool hasDefaultUVSet = false; + TF_FOR_ALL(iter, primvars) + { + const UsdGeomPrimvar& primvar = *iter; + const SdfValueTypeName typeName = primvar.GetTypeName(); + if (typeName == SdfValueTypeNames->TexCoord2fArray + || (UsdMayaReadUtil::ReadFloat2AsUV() && typeName == SdfValueTypeNames->Float2Array)) { + const TfToken fullName = primvar.GetPrimvarName(); + if (fullName == _meshTokens->map1 || fullName == UsdUtilsGetPrimaryUVSetName()) { + hasDefaultUVSet = true; + } + } + } + + TF_FOR_ALL(iter, primvars) { const UsdGeomPrimvar& primvar = *iter; const TfToken name = primvar.GetBaseName(); @@ -646,7 +674,7 @@ UsdMayaMeshReadUtils::assignPrimvarsToMesh(const UsdGeomMesh& mesh, // Otherwise, if env variable for reading Float2 // as uv sets is turned on, we assume that Float2Array primvars // are UV sets. - if (!assignUVSetPrimvarToMesh(primvar, meshFn)) { + if (!assignUVSetPrimvarToMesh(primvar, meshFn, hasDefaultUVSet)) { TF_WARN("Unable to retrieve and assign data for UV set <%s> on " "mesh <%s>", name.GetText(), From 80cb46c57b34eea110ab6862e7a7fee9926fd308 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk Date: Fri, 24 Jul 2020 13:18:04 -0400 Subject: [PATCH 2/3] MAYA-105735 Fixed bug and added targetted unit test --- lib/mayaUsd/fileio/utils/meshReadUtils.cpp | 8 +++++++- test/lib/usd/translators/testUsdImportUVSets.py | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/mayaUsd/fileio/utils/meshReadUtils.cpp b/lib/mayaUsd/fileio/utils/meshReadUtils.cpp index a9179228f3..d6a5d9ce43 100644 --- a/lib/mayaUsd/fileio/utils/meshReadUtils.cpp +++ b/lib/mayaUsd/fileio/utils/meshReadUtils.cpp @@ -246,18 +246,24 @@ namespace MStatus status{MS::kSuccess}; MString uvSetName(primvarName.GetText()); + bool createUVSet = true; + if (primvarName == UsdUtilsGetPrimaryUVSetName()) { // We assume that the primary USD UV set maps to Maya's default 'map1' // set which always exists, so we shouldn't try to create it. uvSetName = _meshTokens->map1.GetText(); + createUVSet = false; } else if (!hasDefaultUVSet) { // If map1 still exists, we rename and re-use it: MStringArray uvSetNames; meshFn.getUVSetNames(uvSetNames); if (uvSetNames[0] == _meshTokens->map1.GetText()) { meshFn.renameUVSet(_meshTokens->map1.GetText(), uvSetName); + createUVSet = false; } - } else { + } + + if (createUVSet) { status = meshFn.createUVSet(uvSetName); if (status != MS::kSuccess) { TF_WARN("Unable to create UV set '%s' for mesh: %s", diff --git a/test/lib/usd/translators/testUsdImportUVSets.py b/test/lib/usd/translators/testUsdImportUVSets.py index 019d3c6d2c..905ea6fc4a 100644 --- a/test/lib/usd/translators/testUsdImportUVSets.py +++ b/test/lib/usd/translators/testUsdImportUVSets.py @@ -192,6 +192,9 @@ def testImportCompressibleUVSets(self): """ mayaCubeMesh = self._GetMayaMesh('CompressibleUVSetsCubeShape') + # We should not see the default "map1" UV set: + self.assertNotIn("map1", mayaCubeMesh.getUVSetNames()) + # ALL face vertices should have the same value. uvSetName = 'ConstantInterpSet' expectedValues = {} From 5647d3eee4a1bf1e5a30fe3d5daee438f524fc58 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk Date: Tue, 28 Jul 2020 10:11:42 -0400 Subject: [PATCH 3/3] MAYA-105735 Small updates from comments --- lib/mayaUsd/fileio/utils/meshReadUtils.cpp | 37 ++++++++++----------- lib/mayaUsd/fileio/utils/meshReadUtils.h | 10 +++--- lib/mayaUsd/fileio/utils/meshWriteUtils.cpp | 3 +- lib/usd/translators/meshWriter.cpp | 6 ++-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/mayaUsd/fileio/utils/meshReadUtils.cpp b/lib/mayaUsd/fileio/utils/meshReadUtils.cpp index d6a5d9ce43..046b0606ee 100644 --- a/lib/mayaUsd/fileio/utils/meshReadUtils.cpp +++ b/lib/mayaUsd/fileio/utils/meshReadUtils.cpp @@ -51,16 +51,13 @@ PXR_NAMESPACE_OPEN_SCOPE -TF_DEFINE_PUBLIC_TOKENS(UsdMayaMeshColorSetTokens, - PXRUSDMAYA_MESH_COLOR_SET_TOKENS); +TF_DEFINE_PUBLIC_TOKENS(UsdMayaMeshPrimvarTokens, + PXRUSDMAYA_MESH_PRIMVAR_TOKENS); // These tokens are supported Maya attributes used for Mesh surfaces TF_DEFINE_PRIVATE_TOKENS( _meshTokens, - // Default UV set name in Maya - (map1) - // we capitalize this because it doesn't correspond to an actual attribute (USD_EmitNormals) @@ -251,18 +248,19 @@ namespace if (primvarName == UsdUtilsGetPrimaryUVSetName()) { // We assume that the primary USD UV set maps to Maya's default 'map1' // set which always exists, so we shouldn't try to create it. - uvSetName = _meshTokens->map1.GetText(); + uvSetName = UsdMayaMeshPrimvarTokens->DefaultMayaTexcoordName.GetText(); createUVSet = false; } else if (!hasDefaultUVSet) { // If map1 still exists, we rename and re-use it: MStringArray uvSetNames; meshFn.getUVSetNames(uvSetNames); - if (uvSetNames[0] == _meshTokens->map1.GetText()) { - meshFn.renameUVSet(_meshTokens->map1.GetText(), uvSetName); + if (uvSetNames[0] == UsdMayaMeshPrimvarTokens->DefaultMayaTexcoordName.GetText()) { + meshFn.renameUVSet( + UsdMayaMeshPrimvarTokens->DefaultMayaTexcoordName.GetText(), uvSetName); createUVSet = false; } } - + if (createUVSet) { status = meshFn.createUVSet(uvSetName); if (status != MS::kSuccess) { @@ -337,17 +335,17 @@ namespace // Note that if BOTH displayColor and displayOpacity are authored, they will // be imported as separate color sets. We do not attempt to combine them // into a single color set. - if (primvarName == UsdMayaMeshColorSetTokens->DisplayOpacityColorSetName && + if (primvarName == UsdMayaMeshPrimvarTokens->DisplayOpacityColorSetName && typeName == SdfValueTypeNames->FloatArray) { if (!UsdMayaRoundTripUtil::IsAttributeUserAuthored(mesh.GetDisplayColorPrimvar())) { - colorSetName = UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetText(); + colorSetName = UsdMayaMeshPrimvarTokens->DisplayColorColorSetName.GetText(); } } // We'll need to convert colors from linear to display if this color set is // for display colors. const bool isDisplayColor = - (colorSetName == UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetText()); + (colorSetName == UsdMayaMeshPrimvarTokens->DisplayColorColorSetName.GetText()); // Get the raw data before applying any indexing. We'll only populate one // of these arrays based on the primvar's typeName, and we'll also set the @@ -521,7 +519,7 @@ namespace const MString colorSetName = colorSetNames[i]; if (std::string(colorSetName.asChar()) - == UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetString()) + == UsdMayaMeshPrimvarTokens->DisplayColorColorSetName.GetString()) { const auto csRep = meshFn.getColorRepresentation(colorSetName); @@ -629,22 +627,21 @@ UsdMayaMeshReadUtils::assignPrimvarsToMesh(const UsdGeomMesh& mesh, // will use that slot. If not, the first texcoord stream to load will replace the default map1 // stream. bool hasDefaultUVSet = false; - TF_FOR_ALL(iter, primvars) + for (const UsdGeomPrimvar& primvar: primvars) { - const UsdGeomPrimvar& primvar = *iter; const SdfValueTypeName typeName = primvar.GetTypeName(); if (typeName == SdfValueTypeNames->TexCoord2fArray || (UsdMayaReadUtil::ReadFloat2AsUV() && typeName == SdfValueTypeNames->Float2Array)) { const TfToken fullName = primvar.GetPrimvarName(); - if (fullName == _meshTokens->map1 || fullName == UsdUtilsGetPrimaryUVSetName()) { + if (fullName == UsdMayaMeshPrimvarTokens->DefaultMayaTexcoordName + || fullName == UsdUtilsGetPrimaryUVSetName()) { hasDefaultUVSet = true; } } } - TF_FOR_ALL(iter, primvars) + for (const UsdGeomPrimvar& primvar: primvars) { - const UsdGeomPrimvar& primvar = *iter; const TfToken name = primvar.GetBaseName(); const TfToken fullName = primvar.GetPrimvarName(); const SdfValueTypeName typeName = primvar.GetTypeName(); @@ -662,8 +659,8 @@ UsdMayaMeshReadUtils::assignPrimvarsToMesh(const UsdGeomMesh& mesh, // authored by the user, for example if it was generated by shader // values and not an authored colorset/entity. // If it was not really authored, we skip the primvar. - if (name == UsdMayaMeshColorSetTokens->DisplayColorColorSetName || - name == UsdMayaMeshColorSetTokens->DisplayOpacityColorSetName) { + if (name == UsdMayaMeshPrimvarTokens->DisplayColorColorSetName || + name == UsdMayaMeshPrimvarTokens->DisplayOpacityColorSetName) { if (!UsdMayaRoundTripUtil::IsAttributeUserAuthored(primvar)) { continue; } diff --git a/lib/mayaUsd/fileio/utils/meshReadUtils.h b/lib/mayaUsd/fileio/utils/meshReadUtils.h index 372319009b..fea81feb82 100644 --- a/lib/mayaUsd/fileio/utils/meshReadUtils.h +++ b/lib/mayaUsd/fileio/utils/meshReadUtils.h @@ -37,13 +37,15 @@ PXR_NAMESPACE_OPEN_SCOPE class UsdGeomMesh; -#define PXRUSDMAYA_MESH_COLOR_SET_TOKENS \ +#define PXRUSDMAYA_MESH_PRIMVAR_TOKENS \ ((DisplayColorColorSetName, "displayColor")) \ - ((DisplayOpacityColorSetName, "displayOpacity")) + ((DisplayOpacityColorSetName, "displayOpacity")) \ + ((DefaultMayaTexcoordName, "map1")) + -TF_DECLARE_PUBLIC_TOKENS(UsdMayaMeshColorSetTokens, +TF_DECLARE_PUBLIC_TOKENS(UsdMayaMeshPrimvarTokens, MAYAUSD_CORE_PUBLIC, - PXRUSDMAYA_MESH_COLOR_SET_TOKENS); + PXRUSDMAYA_MESH_PRIMVAR_TOKENS); /// Utilities for dealing with USD and RenderMan for Maya mesh/subdiv tags. namespace UsdMayaMeshReadUtils diff --git a/lib/mayaUsd/fileio/utils/meshWriteUtils.cpp b/lib/mayaUsd/fileio/utils/meshWriteUtils.cpp index fd2a98db19..d06f58fb97 100644 --- a/lib/mayaUsd/fileio/utils/meshWriteUtils.cpp +++ b/lib/mayaUsd/fileio/utils/meshWriteUtils.cpp @@ -18,6 +18,7 @@ #include "meshWriteUtils.h" #include +#include #include #include @@ -835,7 +836,7 @@ UsdMayaMeshWriteUtils::writeUVSetsAsVec2fPrimvars(const MFnMesh& meshFn, // behavior, and the name to which it exports. // The UV Set "map1" is renamed st. This is a Pixar/USD convention. TfToken setName(uvSetNames[i].asChar()); - if (setName == "map1") { + if (setName == UsdMayaMeshPrimvarTokens->DefaultMayaTexcoordName.GetText()) { setName = UsdUtilsGetPrimaryUVSetName(); } diff --git a/lib/usd/translators/meshWriter.cpp b/lib/usd/translators/meshWriter.cpp index 97f175b8b8..d41d1e8664 100644 --- a/lib/usd/translators/meshWriter.cpp +++ b/lib/usd/translators/meshWriter.cpp @@ -260,18 +260,18 @@ PxrUsdTranslators_MeshWriter::writeMeshAttrs(const UsdTimeCode& usdTime, bool isDisplayColor = false; - if (colorSetName == UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetString()) { + if (colorSetName == UsdMayaMeshPrimvarTokens->DisplayColorColorSetName.GetString()) { if (!_GetExportArgs().exportDisplayColor) { continue; } isDisplayColor=true; } - if (colorSetName == UsdMayaMeshColorSetTokens->DisplayOpacityColorSetName.GetString()) { + if (colorSetName == UsdMayaMeshPrimvarTokens->DisplayOpacityColorSetName.GetString()) { TF_WARN("Mesh \"%s\" has a color set named \"%s\", " "which is a reserved Primvar name in USD. Skipping...", finalMesh.fullPathName().asChar(), - UsdMayaMeshColorSetTokens->DisplayOpacityColorSetName + UsdMayaMeshPrimvarTokens->DisplayOpacityColorSetName .GetText()); continue; }