Skip to content

Commit

Permalink
Merge pull request #3190 from Autodesk/bailp/EMSUSD-243/ref-without-d…
Browse files Browse the repository at this point in the history
…efault-prim

EMSUSD-243 load reference and payload without default prim
  • Loading branch information
seando-adsk authored Jul 5, 2023
2 parents 28f3469 + e3b0935 commit fd98bae
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 76 deletions.
2 changes: 2 additions & 0 deletions lib/usdUfe/ufe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ if(CMAKE_UFE_V2_FEATURES_AVAILABLE)
UsdUndoAddNewPrimCommand.cpp
UsdUndoAddPayloadCommand.cpp
UsdUndoAddReferenceCommand.cpp
UsdUndoAddRefOrPayloadCommand.cpp
UsdUndoClearPayloadsCommand.cpp
UsdUndoClearReferencesCommand.cpp
UsdUndoCreateGroupCommand.cpp
Expand Down Expand Up @@ -65,6 +66,7 @@ if(CMAKE_UFE_V2_FEATURES_AVAILABLE)
UsdUndoAddNewPrimCommand.h
UsdUndoAddPayloadCommand.h
UsdUndoAddReferenceCommand.h
UsdUndoAddRefOrPayloadCommand.h
UsdUndoClearPayloadsCommand.h
UsdUndoClearReferencesCommand.h
UsdUndoCreateGroupCommand.h
Expand Down
27 changes: 7 additions & 20 deletions lib/usdUfe/ufe/UsdUndoAddPayloadCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,23 @@

#include "UsdUndoAddPayloadCommand.h"

#include <pxr/base/tf/stringUtils.h>
#include <pxr/usd/sdf/path.h>

namespace USDUFE_NS_DEF {

UsdUndoAddPayloadCommand::UsdUndoAddPayloadCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
bool prepend)
: _prim(prim)
, _sdfPayload()
, _filePath(filePath)
, _listPos(
prepend ? PXR_NS::UsdListPositionBackOfPrependList
: PXR_NS::UsdListPositionBackOfAppendList)
: UsdUndoAddPayloadCommand(prim, filePath, {}, prepend)
{
}

void UsdUndoAddPayloadCommand::executeImplementation()
UsdUndoAddPayloadCommand::UsdUndoAddPayloadCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
const std::string& primPath,
bool prepend)
: UsdUndoAddRefOrPayloadCommand(prim, filePath, primPath, getListPosition(prepend), true)
{
if (!_prim.IsValid())
return;

if (PXR_NS::TfStringEndsWith(_filePath, ".mtlx")) {
_sdfPayload = PXR_NS::SdfPayload(_filePath, PXR_NS::SdfPath("/MaterialX"));
} else {
_sdfPayload = PXR_NS::SdfPayload(_filePath);
}
PXR_NS::UsdPayloads primPayloads = _prim.GetPayloads();
primPayloads.AddPayload(_sdfPayload, _listPos);
}

} // namespace USDUFE_NS_DEF
25 changes: 7 additions & 18 deletions lib/usdUfe/ufe/UsdUndoAddPayloadCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,24 @@
#ifndef USD_UFE_ADD_PAYLOAD_COMMAND
#define USD_UFE_ADD_PAYLOAD_COMMAND

#include <usdUfe/base/api.h>
#include <usdUfe/ufe/UsdUndoableCommand.h>

#include <pxr/usd/usd/payloads.h>
#include <pxr/usd/usd/prim.h>

#include <ufe/undoableCommand.h>

#include <string>
#include <usdUfe/ufe/UsdUndoAddRefOrPayloadCommand.h>

namespace USDUFE_NS_DEF {

//! \brief Command to add a payload to a prim.
class USDUFE_PUBLIC UsdUndoAddPayloadCommand : public UsdUndoableCommand<Ufe::UndoableCommand>
class USDUFE_PUBLIC UsdUndoAddPayloadCommand : public UsdUndoAddRefOrPayloadCommand
{
public:
UsdUndoAddPayloadCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
bool prepend);

protected:
void executeImplementation() override;

private:
PXR_NS::UsdPrim _prim;
PXR_NS::SdfPayload _sdfPayload;
std::string _filePath;
PXR_NS::UsdListPosition _listPos;
UsdUndoAddPayloadCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
const std::string& primPath,
bool prepend);
};

} // namespace USDUFE_NS_DEF
Expand Down
145 changes: 145 additions & 0 deletions lib/usdUfe/ufe/UsdUndoAddRefOrPayloadCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
//
// Copyright 2023 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "UsdUndoAddRefOrPayloadCommand.h"

#include <pxr/base/tf/stringUtils.h>
#include <pxr/usd/sdf/layer.h>
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/usd/payloads.h>
#include <pxr/usd/usd/references.h>

namespace USDUFE_NS_DEF {

using namespace PXR_NS;

static std::string validatePrimSpec(const UsdPrim& prim, const SdfPrimSpecHandle& primSpec)
{
if (!primSpec)
return "is not valid";

// A common error is to reference a prim that is not the same type as the prim
// that contains the reference. Since only the type of the prim that contains
// the reference is used, the referenced prim might not show up.
//
// This happens a lot when trying to reference geometry (mesh) instead of the
// prim containing the geometry. Of vis-versa, referencing a prim inside a mesh.
const std::string& primType = prim.GetTypeName();
const std::string& targetType = primSpec->GetTypeName();
if (primType != targetType)
return TfStringPrintf(
"does not have the same type as the targeted prim: [%s] vs [%s]",
primType.c_str(),
targetType.c_str());

return "";
}

static PXR_NS::SdfPath
getPrimPath(const UsdPrim& prim, const std::string& filePath, const std::string& primPath)
{
// When an explicit prim path was given, use that.
if (!primPath.empty())
return SdfPath(primPath);

// If no prim path were specified and we are referencing a MaterialX file
// then use the MaterialX prim as the target for the reference.
//
// TODO: should we force this even when the referenced file has a default prim?
if (TfStringEndsWith(filePath, ".mtlx"))
return SdfPath("/MaterialX");

// Retrieve the layer for analysis.
//
// Note: we don't print any warning if the layer cannot be found as we assume
// the load itself will also fail and print an error.
SdfLayerRefPtr layerRef = SdfLayer::FindOrOpen(filePath);
if (!layerRef)
return SdfPath();

// If the referenced file has a default prim, leave the prim path empty.
if (layerRef->HasDefaultPrim()) {
TfToken primName = layerRef->GetDefaultPrim();
SdfPrimSpecHandle primSpec = layerRef->GetPrimAtPath(SdfPath(primName.GetText()));
const std::string errorMessage = validatePrimSpec(prim, primSpec);
if (!errorMessage.empty())
TF_WARN("The default prim in file [%s] %s.", filePath.c_str(), errorMessage.c_str());
return SdfPath();
}

// If the referenced file has no default prim, return the path to the first
// valid root prim we find.

TF_STATUS(
"The file [%s] does not contain a default prim, the first valid root prim "
"will be used.",
filePath.c_str());

std::string errorMessage;
for (const SdfPrimSpecHandle primSpec : layerRef->GetRootPrims()) {
if (!primSpec)
continue;

errorMessage = validatePrimSpec(prim, primSpec);
if (errorMessage.empty())
return primSpec->GetPath();
}

if (errorMessage.empty()) {
TF_WARN("Could not find any valid root prim.");
} else {
TF_WARN("Could not find a valid root prim, the root prim %s.", errorMessage.c_str());
}

return SdfPath();
}

/* static */ UsdListPosition UsdUndoAddRefOrPayloadCommand::getListPosition(bool prepend)
{
return prepend ? UsdListPositionBackOfPrependList : UsdListPositionBackOfAppendList;
}

UsdUndoAddRefOrPayloadCommand::UsdUndoAddRefOrPayloadCommand(
const UsdPrim& prim,
const std::string& filePath,
const std::string& primPath,
UsdListPosition listPos,
bool isPayload)
: _prim(prim)
, _filePath(filePath)
, _primPath(primPath)
, _listPos(listPos)
, _isPayload(isPayload)
{
}

void UsdUndoAddRefOrPayloadCommand::executeImplementation()
{
if (!_prim.IsValid())
return;

SdfPath primPath = getPrimPath(_prim, _filePath, _primPath);
if (_isPayload) {
SdfPayload payload(_filePath, primPath);
UsdPayloads primPayloads = _prim.GetPayloads();
primPayloads.AddPayload(payload, _listPos);
} else {
SdfReference ref(_filePath, primPath);
UsdReferences primRefs = _prim.GetReferences();
primRefs.AddReference(ref, _listPos);
}
}

} // namespace USDUFE_NS_DEF
57 changes: 57 additions & 0 deletions lib/usdUfe/ufe/UsdUndoAddRefOrPayloadCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Copyright 2023 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef USD_UFE_ADD_REF_OR_PAYLOAD_COMMAND
#define USD_UFE_ADD_REF_OR_PAYLOAD_COMMAND

#include <usdUfe/base/api.h>
#include <usdUfe/ufe/UsdUndoableCommand.h>

#include <pxr/usd/usd/common.h>
#include <pxr/usd/usd/prim.h>

#include <ufe/undoableCommand.h>

#include <string>

namespace USDUFE_NS_DEF {

//! \brief Command to add a reference or payload to a prim.
class USDUFE_PUBLIC UsdUndoAddRefOrPayloadCommand : public UsdUndoableCommand<Ufe::UndoableCommand>
{
public:
UsdUndoAddRefOrPayloadCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
const std::string& primPath,
PXR_NS::UsdListPosition listPos,
bool isPayload);

protected:
static PXR_NS::UsdListPosition getListPosition(bool prepend);

void executeImplementation() override;

private:
PXR_NS::UsdPrim _prim;
std::string _filePath;
std::string _primPath;
PXR_NS::UsdListPosition _listPos;
bool _isPayload;
};

} // namespace USDUFE_NS_DEF

#endif /* USD_UFE_ADD_REF_OR_PAYLOAD_COMMAND */
27 changes: 7 additions & 20 deletions lib/usdUfe/ufe/UsdUndoAddReferenceCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,23 @@
//
#include "UsdUndoAddReferenceCommand.h"

#include <pxr/base/tf/stringUtils.h>
#include <pxr/usd/sdf/path.h>

namespace USDUFE_NS_DEF {

//! \brief Command to add a reference to a prim.
UsdUndoAddReferenceCommand::UsdUndoAddReferenceCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
bool prepend)
: _prim(prim)
, _sdfRef()
, _filePath(filePath)
, _listPos(
prepend ? PXR_NS::UsdListPositionBackOfPrependList
: PXR_NS::UsdListPositionBackOfAppendList)
: UsdUndoAddReferenceCommand(prim, filePath, {}, prepend)
{
}

void UsdUndoAddReferenceCommand::executeImplementation()
UsdUndoAddReferenceCommand::UsdUndoAddReferenceCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
const std::string& primPath,
bool prepend)
: UsdUndoAddRefOrPayloadCommand(prim, filePath, primPath, getListPosition(prepend), false)
{
if (!_prim.IsValid())
return;

_sdfRef = PXR_NS::TfStringEndsWith(_filePath, ".mtlx")
? PXR_NS::SdfReference(_filePath, PXR_NS::SdfPath("/MaterialX"))
: PXR_NS::SdfReference(_filePath);

PXR_NS::UsdReferences primRefs = _prim.GetReferences();
primRefs.AddReference(_sdfRef, _listPos);
}

} // namespace USDUFE_NS_DEF
25 changes: 7 additions & 18 deletions lib/usdUfe/ufe/UsdUndoAddReferenceCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,24 @@
#ifndef USD_UFE_ADD_REFERENCE_COMMAND
#define USD_UFE_ADD_REFERENCE_COMMAND

#include <usdUfe/base/api.h>
#include <usdUfe/ufe/UsdUndoableCommand.h>

#include <pxr/usd/usd/prim.h>
#include <pxr/usd/usd/references.h>

#include <ufe/undoableCommand.h>

#include <string>
#include <usdUfe/ufe/UsdUndoAddRefOrPayloadCommand.h>

namespace USDUFE_NS_DEF {

//! \brief Command to add a reference to a prim.
class USDUFE_PUBLIC UsdUndoAddReferenceCommand : public UsdUndoableCommand<Ufe::UndoableCommand>
class USDUFE_PUBLIC UsdUndoAddReferenceCommand : public UsdUndoAddRefOrPayloadCommand
{
public:
UsdUndoAddReferenceCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
bool prepend);

protected:
void executeImplementation() override;

private:
PXR_NS::UsdPrim _prim;
PXR_NS::SdfReference _sdfRef;
std::string _filePath;
PXR_NS::UsdListPosition _listPos;
UsdUndoAddReferenceCommand(
const PXR_NS::UsdPrim& prim,
const std::string& filePath,
const std::string& primPath,
bool prepend);
};

} // namespace USDUFE_NS_DEF
Expand Down
Loading

0 comments on commit fd98bae

Please sign in to comment.