Skip to content

Commit

Permalink
Merge pull request #1792 from AnimalLogic/J-Mo63/add-file-format-id-t…
Browse files Browse the repository at this point in the history
…o-layer-manager

Added file format attribute to LayerManager and improved format detection for serialised layers
  • Loading branch information
Krystian Ligenza authored Nov 22, 2021
2 parents a4463b8 + f485f4b commit 82ac60a
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 124 deletions.
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
= 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

0 comments on commit 82ac60a

Please sign in to comment.