Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added file format attribute to LayerManager and improved format detection for serialised layers #1792

Merged
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
72 changes: 42 additions & 30 deletions lib/mayaUsd/nodes/layerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <pxr/base/tf/instantiateType.h>
#include <pxr/base/tf/weakBase.h>
#include <pxr/usd/ar/resolver.h>
#include <pxr/usd/sdf/textFileFormat.h>
#include <pxr/usd/usd/editTarget.h>
#include <pxr/usd/usd/usdFileFormat.h>
Expand Down Expand Up @@ -107,34 +108,6 @@ MStatus disconnectCompoundArrayPlug(MPlug arrayPlug)
return dgmod.doIt();
}

SdfFileFormatConstPtr
getFileFormatForLayer(const std::string& identifierVal, const std::string& serializedVal)
{
// If there is serialized data and it does not start with "#usda" then the format is Sdf.
// Else we look at the file extension to determine what it should be, which could be Sdf, Usd,
// Usdc, or Usda.

SdfFileFormatConstPtr fileFormat;

if (!serializedVal.empty() && !TfStringStartsWith(serializedVal, "#usda ")) {
fileFormat = SdfFileFormat::FindById(SdfTextFileFormatTokens->Id);
} else {
// In order to make the layer reloadable by SdfLayer::Reload(), we need the
// correct file format from identifier.
if (TfStringEndsWith(identifierVal, ".usd")) {
fileFormat = SdfFileFormat::FindById(UsdUsdFileFormatTokens->Id);
} else if (TfStringEndsWith(identifierVal, ".usdc")) {
fileFormat = SdfFileFormat::FindById(UsdUsdcFileFormatTokens->Id);
} else if (TfStringEndsWith(identifierVal, ".sdf")) {
fileFormat = SdfFileFormat::FindById(SdfTextFileFormatTokens->Id);
} else {
fileFormat = SdfFileFormat::FindById(UsdUsdaFileFormatTokens->Id);
}
}

return fileFormat;
}

MayaUsd::LayerManager* findNode()
{
// Check for cached layer manager before searching
Expand Down Expand Up @@ -525,12 +498,16 @@ MStatus addLayerToBuilder(
MDataHandle layersElemHandle = builder.addLast(&status);
CHECK_MSTATUS_AND_RETURN_IT(status);
MDataHandle idHandle = layersElemHandle.child(lm->identifier);
MDataHandle fileFormatIdHandle = layersElemHandle.child(lm->fileFormatId);
MDataHandle serializedHandle = layersElemHandle.child(lm->serialized);
MDataHandle anonHandle = layersElemHandle.child(lm->anonymous);

idHandle.setString(UsdMayaUtil::convert(layer->GetIdentifier()));
anonHandle.setBool(isAnon);

auto fileFormatIdToken = layer->GetFileFormat()->GetFormatId();
fileFormatIdHandle.setString(UsdMayaUtil::convert(fileFormatIdToken.GetString()));

std::string temp;
if (!stubOnly && ((exportOnlyIfDirty && layer->IsDirty()) || !exportOnlyIfDirty)) {
if (!layer->ExportToString(&temp)) {
Expand Down Expand Up @@ -779,9 +756,11 @@ void LayerDatabase::loadLayersPostRead(void*)
MPlug allLayersPlug(lm->thisMObject(), lm->layers);
MPlug singleLayerPlug;
MPlug idPlug;
MPlug fileFormatIdPlug;
MPlug anonymousPlug;
MPlug serializedPlug;
std::string identifierVal;
std::string fileFormatIdVal;
std::string serializedVal;
SdfLayerRefPtr layer;
std::vector<SdfLayerRefPtr> createdLayers;
Expand All @@ -792,6 +771,7 @@ void LayerDatabase::loadLayersPostRead(void*)

singleLayerPlug = allLayersPlug.elementByPhysicalIndex(i, &status);
idPlug = singleLayerPlug.child(lm->identifier, &status);
fileFormatIdPlug = singleLayerPlug.child(lm->fileFormatId, &status);
anonymousPlug = singleLayerPlug.child(lm->anonymous, &status);
serializedPlug = singleLayerPlug.child(lm->serialized, &status);

Expand All @@ -802,6 +782,13 @@ void LayerDatabase::loadLayersPostRead(void*)
continue;
}

fileFormatIdVal = fileFormatIdPlug.asString(MDGContext::fsNormal, &status).asChar();
if (fileFormatIdVal.empty()) {
MGlobal::displayInfo(
MString("No file format in ") + fileFormatIdPlug.partialName(true)
+ " plug. Will use identifier to work it out.");
}

bool layerContainsEdits = true;
serializedVal = serializedPlug.asString(MDGContext::fsNormal, &status).asChar();
if (serializedVal.empty()) {
Expand All @@ -824,8 +811,19 @@ void LayerDatabase::loadLayersPostRead(void*)
// identifier, which could cause an error. This seems unlikely, but we have a
// discussion with Pixar to find a way to avoid this.

SdfFileFormatConstPtr fileFormat
= getFileFormatForLayer(identifierVal, serializedVal);
SdfFileFormatConstPtr fileFormat;
if (!fileFormatIdVal.empty()) {
fileFormat = SdfFileFormat::FindById(TfToken(fileFormatIdVal));
} else {
fileFormat = SdfFileFormat::FindByExtension(
ArGetResolver().GetExtension(identifierVal));
if (!fileFormat) {
MGlobal::displayError(
MString("Cannot determine file format for identifier '")
+ identifierVal.c_str() + "' for plug " + idPlug.partialName(true));
continue;
}
}

if (layerContainsEdits) {
// In order to make the layer reloadable by SdfLayer::Reload(), we hack the
Expand Down Expand Up @@ -984,6 +982,7 @@ const MTypeId LayerManager::typeId(0x58000097);

MObject LayerManager::layers = MObject::kNullObj;
MObject LayerManager::identifier = MObject::kNullObj;
MObject LayerManager::fileFormatId = MObject::kNullObj;
MObject LayerManager::serialized = MObject::kNullObj;
MObject LayerManager::anonymous = MObject::kNullObj;

Expand Down Expand Up @@ -1027,6 +1026,16 @@ MStatus LayerManager::initialize()
stat = addAttribute(identifier);
CHECK_MSTATUS_AND_RETURN_IT(stat);

fileFormatId

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't share the same implementation of LayerManager, it would be good to add a test for this new addition to validate the core implementation as well. I won't make it a blocker for this change, but please open a new PR with it.

= fn_str.create("fileFormatId", "fid", MFnData::kString, MObject::kNullObj, &stat);
CHECK_MSTATUS_AND_RETURN_IT(stat);
fn_str.setCached(true);
fn_str.setReadable(true);
fn_str.setStorable(true);
fn_str.setHidden(true);
stat = addAttribute(fileFormatId);
CHECK_MSTATUS_AND_RETURN_IT(stat);

serialized = fn_str.create("serialized", "szd", MFnData::kString, MObject::kNullObj, &stat);
CHECK_MSTATUS_AND_RETURN_IT(stat);
fn_str.setCached(true);
Expand All @@ -1053,6 +1062,9 @@ MStatus LayerManager::initialize()
stat = fn_cmp.addChild(identifier);
CHECK_MSTATUS_AND_RETURN_IT(stat);

stat = fn_cmp.addChild(fileFormatId);
CHECK_MSTATUS_AND_RETURN_IT(stat);

stat = fn_cmp.addChild(serialized);
CHECK_MSTATUS_AND_RETURN_IT(stat);

Expand Down
1 change: 1 addition & 0 deletions lib/mayaUsd/nodes/layerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class MAYAUSD_CORE_PUBLIC LayerManager : public MPxNode

static MObject layers;
static MObject identifier;
static MObject fileFormatId;
static MObject serialized;
static MObject anonymous;

Expand Down
41 changes: 29 additions & 12 deletions plugin/al/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "AL/maya/utils/Utils.h"
#include "AL/usdmaya/DebugCodes.h"
#include "AL/usdmaya/TypeIDs.h"
#include "pxr/usd/ar/resolver.h"

#include <mayaUsd/listeners/notice.h>

Expand Down Expand Up @@ -267,6 +268,7 @@ AL_MAYA_DEFINE_NODE(LayerManager, AL_USDMAYA_LAYERMANAGER, AL_usdmaya);
// serialization
MObject LayerManager::m_layers = MObject::kNullObj;
MObject LayerManager::m_identifier = MObject::kNullObj;
MObject LayerManager::m_fileFormatId = MObject::kNullObj;
MObject LayerManager::m_serialized = MObject::kNullObj;
MObject LayerManager::m_anonymous = MObject::kNullObj;

Expand Down Expand Up @@ -299,6 +301,8 @@ MStatus LayerManager::initialise()

// add attributes to store the serialization info
m_identifier = addStringAttr("identifier", "id", kCached | kReadable | kStorable | kHidden);
m_fileFormatId
= addStringAttr("fileFormatId", "fid", kCached | kReadable | kStorable | kHidden);
m_serialized
= addStringAttr("serialized", "szd", kCached | kReadable | kStorable | kHidden);
m_anonymous
Expand All @@ -308,7 +312,7 @@ MStatus LayerManager::initialise()
"lyr",
kCached | kReadable | kWritable | kStorable | kConnectable | kHidden | kArray
| kUsesArrayDataBuilder,
{ m_identifier, m_serialized, m_anonymous });
{ m_identifier, m_fileFormatId, m_serialized, m_anonymous });
} catch (const MStatus& status) {
return status;
}
Expand Down Expand Up @@ -466,6 +470,9 @@ MStatus LayerManager::populateSerialisationAttributes()
AL_MAYA_CHECK_ERROR(status, errorString);
MDataHandle idHandle = layersElemHandle.child(m_identifier);
idHandle.setString(AL::maya::utils::convert(layer->GetIdentifier()));
MDataHandle fileFormatIdHandle = layersElemHandle.child(m_fileFormatId);
auto fileFormatIdToken = layer->GetFileFormat()->GetFormatId();
fileFormatIdHandle.setString(AL::maya::utils::convert(fileFormatIdToken.GetString()));
MDataHandle serializedHandle = layersElemHandle.child(m_serialized);
layer->ExportToString(&temp);
serializedHandle.setString(AL::maya::utils::convert(temp));
Expand Down Expand Up @@ -518,9 +525,11 @@ void LayerManager::loadAllLayers()
MPlug allLayersPlug = layersPlug();
MPlug singleLayerPlug;
MPlug idPlug;
MPlug fileFormatIdPlug;
MPlug anonymousPlug;
MPlug serializedPlug;
std::string identifierVal;
std::string fileFormatIdVal;
std::string serializedVal;
SdfLayerRefPtr layer;
// We DON'T want to use evaluate num elements, because we don't want to trigger
Expand All @@ -531,6 +540,8 @@ void LayerManager::loadAllLayers()
AL_MAYA_CHECK_ERROR_CONTINUE(status, errorString);
idPlug = singleLayerPlug.child(m_identifier, &status);
AL_MAYA_CHECK_ERROR_CONTINUE(status, errorString);
fileFormatIdPlug = singleLayerPlug.child(m_fileFormatId, &status);
AL_MAYA_CHECK_ERROR_CONTINUE(status, errorString);
anonymousPlug = singleLayerPlug.child(m_anonymous, &status);
AL_MAYA_CHECK_ERROR_CONTINUE(status, errorString);
serializedPlug = singleLayerPlug.child(m_serialized, &status);
Expand All @@ -543,6 +554,13 @@ void LayerManager::loadAllLayers()
MString("Error - plug ") + idPlug.partialName(true) + "had empty identifier");
continue;
}
fileFormatIdVal = fileFormatIdPlug.asString(MDGContext::fsNormal, &status).asChar();
AL_MAYA_CHECK_ERROR_CONTINUE(status, errorString);
if (fileFormatIdVal.empty()) {
MGlobal::displayInfo(
MString("No file format in ") + fileFormatIdPlug.partialName(true)
+ " plug. Will use identifier to work it out.");
}
serializedVal = serializedPlug.asString(MDGContext::fsNormal, &status).asChar();
AL_MAYA_CHECK_ERROR_CONTINUE(status, errorString);
if (serializedVal.empty()) {
Expand Down Expand Up @@ -570,18 +588,17 @@ void LayerManager::loadAllLayers()
// discussion with Pixar to find a way to avoid this.

SdfFileFormatConstPtr fileFormat;
if (TfStringStartsWith(serializedVal, "#usda ")) {
// In order to make the layer reloadable by SdfLayer::Reload(), we need the
// correct file format from identifier.
if (TfStringEndsWith(identifierVal, ".usd")) {
fileFormat = SdfFileFormat::FindById(UsdUsdFileFormatTokens->Id);
} else if (TfStringEndsWith(identifierVal, ".usdc")) {
fileFormat = SdfFileFormat::FindById(UsdUsdcFileFormatTokens->Id);
} else {
fileFormat = SdfFileFormat::FindById(UsdUsdaFileFormatTokens->Id);
}
if (!fileFormatIdVal.empty()) {
fileFormat = SdfFileFormat::FindById(TfToken(fileFormatIdVal));
} else {
fileFormat = SdfFileFormat::FindById(SdfTextFileFormatTokens->Id);
fileFormat = SdfFileFormat::FindByExtension(
ArGetResolver().GetExtension(identifierVal));
if (!fileFormat) {
MGlobal::displayError(
MString("Cannot determine file format for identifier '")
+ identifierVal.c_str() + "' for plug " + idPlug.partialName(true));
continue;
}
}

// In order to make the layer reloadable by SdfLayer::Reload(), we hack the
Expand Down
1 change: 1 addition & 0 deletions plugin/al/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ class LayerManager
// - they only make sense for a particular index of the parent array-attribute... and it taking
// up the "identifierPlug" name is confusing
AL_DECL_MULTI_CHILD_ATTRIBUTE(identifier);
AL_DECL_MULTI_CHILD_ATTRIBUTE(fileFormatId);
AL_DECL_MULTI_CHILD_ATTRIBUTE(serialized);
AL_DECL_MULTI_CHILD_ATTRIBUTE(anonymous);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ def Scope "blabla"
tempNonConst = manager->identifier();
MPlug idPlug = layersPlug0.child(tempNonConst, &status);
ASSERT_TRUE(status);
tempNonConst = manager->fileFormatId();
MPlug fileFormatIdPlug = layersPlug0.child(tempNonConst, &status);
ASSERT_TRUE(status);
tempNonConst = manager->serialized();
MPlug serializedPlug = layersPlug0.child(tempNonConst, &status);
ASSERT_TRUE(status);
Expand All @@ -364,6 +367,10 @@ def Scope "blabla"
MString(realLayer->GetIdentifier().c_str()),
idPlug.asString(MDGContext::fsNormal, &status));
ASSERT_TRUE(status);
ASSERT_EQ(
MString(realLayer->GetFileFormat()->GetFormatId().GetText()),
fileFormatIdPlug.asString(MDGContext::fsNormal, &status));
ASSERT_TRUE(status);
ASSERT_EQ(MString(LAYER_CONTENTS), serializedPlug.asString(MDGContext::fsNormal, &status));
ASSERT_TRUE(status);
ASSERT_FALSE(anonymousPlug.asBool(MDGContext::fsNormal, &status));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <maya/MSelectionList.h>
#include <maya/MVector.h>

#include <iostream>

using AL::maya::test::buildTempPath;

// #define TEST(X, Y) void X##Y()
Expand Down
Loading