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

Update to newer UFE interface for Create Group #593

Merged
merged 2 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions lib/mayaUsd/ufe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ if(CMAKE_UFE_V2_FEATURES_AVAILABLE)
UsdAttributesHandler.cpp
UsdObject3d.cpp
UsdObject3dHandler.cpp
UsdUndoAddNewPrimCommand.cpp
UsdUndoCreateGroupCommand.cpp
UsdUndoInsertChildCommand.cpp
)
Expand Down Expand Up @@ -92,6 +93,7 @@ if(CMAKE_UFE_V2_FEATURES_AVAILABLE)
UsdContextOpsHandler.h
UsdObject3d.h
UsdObject3dHandler.h
UsdUndoAddNewPrimCommand.h
UsdUndoCreateGroupCommand.h
UsdUndoInsertChildCommand.h
)
Expand Down
34 changes: 33 additions & 1 deletion lib/mayaUsd/ufe/ProxyShapeHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#if UFE_PREVIEW_VERSION_NUM >= 2013
#include <mayaUsd/ufe/UsdUndoInsertChildCommand.h>
#endif

#if UFE_PREVIEW_VERSION_NUM >= 2017
#include <mayaUsd/ufe/UsdUndoCreateGroupCommand.h>
#endif
#endif

MAYAUSD_NS_DEF {
Expand Down Expand Up @@ -170,6 +174,8 @@ Ufe::UndoableCommand::Ptr ProxyShapeHierarchy::insertChildCmd(
}
#endif

#if UFE_PREVIEW_VERSION_NUM < 2017

Ufe::SceneItem::Ptr ProxyShapeHierarchy::createGroup(const Ufe::PathComponent& name) const
{
throw std::runtime_error("ProxyShapeHierarchy::createGroup() not implemented");
Expand All @@ -179,7 +185,33 @@ Ufe::Group ProxyShapeHierarchy::createGroupCmd(const Ufe::PathComponent& name) c
{
throw std::runtime_error("ProxyShapeHierarchy::createGroupCmd not implemented");
}
#endif

#else

Ufe::SceneItem::Ptr ProxyShapeHierarchy::createGroup(const Ufe::Selection& selection, const Ufe::PathComponent& name) const
{
Ufe::SceneItem::Ptr createdItem = nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since these are shared_ptr, you don't really need '= nullptr'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

true


auto usdItem = UsdSceneItem::create(sceneItem()->path(), getUsdRootPrim());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Might be good to comment that this is a bit of a trick, using the USD pseudo-root prim, to take advantage of common code.

UsdUndoCreateGroupCommand::Ptr cmd = UsdUndoCreateGroupCommand::create(usdItem, selection, name.string());
if (cmd) {
cmd->redo();
Copy link
Collaborator

Choose a reason for hiding this comment

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

As per UsdHierarchy.cpp, cmd->execute() slightly more future-proof than cmd->redo().

createdItem = cmd->group();
}

return createdItem;
}

Ufe::UndoableCommand::Ptr ProxyShapeHierarchy::createGroupCmd(const Ufe::Selection& selection, const Ufe::PathComponent& name) const
{
auto usdItem = UsdSceneItem::create(sceneItem()->path(), getUsdRootPrim());

return UsdUndoCreateGroupCommand::create(usdItem, selection, name.string());
}

#endif // UFE_PREVIEW_VERSION_NUM

#endif // UFE_V2_FEATURES_AVAILABLE

} // namespace ufe
} // namespace MayaUsd
7 changes: 7 additions & 0 deletions lib/mayaUsd/ufe/ProxyShapeHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <ufe/hierarchy.h>
#include <ufe/hierarchyHandler.h>
#include <ufe/selection.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not needed, fwd decl.


#include <mayaUsd/base/api.h>
#include <mayaUsd/ufe/UsdSceneItem.h>
Expand Down Expand Up @@ -70,8 +71,14 @@ class MAYAUSD_CORE_PUBLIC ProxyShapeHierarchy : public Ufe::Hierarchy
) override;
#endif

#if UFE_PREVIEW_VERSION_NUM < 2017
Ufe::SceneItem::Ptr createGroup(const Ufe::PathComponent& name) const override;
Ufe::Group createGroupCmd(const Ufe::PathComponent& name) const override;
#else
Ufe::SceneItem::Ptr createGroup(const Ufe::Selection& selection, const Ufe::PathComponent& name) const override;
Ufe::UndoableCommand::Ptr createGroupCmd(const Ufe::Selection& selection, const Ufe::PathComponent& name) const override;
#endif

#endif

private:
Expand Down
10 changes: 10 additions & 0 deletions lib/mayaUsd/ufe/UsdContextOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
#include <mayaUsd/ufe/Utils.h>
#include <mayaUsd/ufe/UsdSceneItem.h>

#if UFE_PREVIEW_VERSION_NUM >= 2017
#include <mayaUsd/ufe/UsdUndoAddNewPrimCommand.h>
#endif

namespace {

// Ufe::ContextItem strings
Expand Down Expand Up @@ -89,6 +93,7 @@ class SetVariantSelectionUndoableCommand : public Ufe::UndoableCommand
const std::string fNewSelection;
};

#if UFE_PREVIEW_VERSION_NUM < 2017
//! \brief Undoable command for add new prim
class AddNewPrimUndoableCommand : public Ufe::UndoableCommand
{
Expand Down Expand Up @@ -143,6 +148,7 @@ class AddNewPrimUndoableCommand : public Ufe::UndoableCommand
PXR_NS::SdfPath _primPath;
PXR_NS::TfToken _primToken;
};
#endif

const char* selectUSDFileScript = R"(
global proc string SelectUSDFileForAddReference()
Expand Down Expand Up @@ -411,7 +417,11 @@ Ufe::UndoableCommand::Ptr UsdContextOps::doOpCmd(const ItemPath& itemPath)

// At this point we know we have 2 arguments to execute the operation.
// itemPath[1] contains the new prim type to create.
#if UFE_PREVIEW_VERSION_NUM < 2017
return std::make_shared<AddNewPrimUndoableCommand>(fItem, itemPath);
#else
return UsdUndoAddNewPrimCommand::create(fItem, itemPath[1], itemPath[1]);
#endif
}
else if (itemPath[0] == kUSDLayerEditorItem) {
// Just open the editor directly and return null so we don't have undo.
Expand Down
28 changes: 27 additions & 1 deletion lib/mayaUsd/ufe/UsdHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ Ufe::UndoableCommand::Ptr UsdHierarchy::insertChildCmd(
}
#endif

#if UFE_PREVIEW_VERSION_NUM < 2017
// Create a transform.
Ufe::SceneItem::Ptr UsdHierarchy::createGroup(const Ufe::PathComponent& name) const
{
Expand Down Expand Up @@ -213,7 +214,32 @@ Ufe::Group UsdHierarchy::createGroupCmd(const Ufe::PathComponent& name) const
createGroupCmd->execute();
return Ufe::Group(createGroupCmd->group(), createGroupCmd);
}
#endif

#else // UFE_PREVIEW_VERSION_NUM


// Create a transform.
Ufe::SceneItem::Ptr UsdHierarchy::createGroup(const Ufe::Selection& selection, const Ufe::PathComponent& name) const
{
Ufe::SceneItem::Ptr createdItem = nullptr;

UsdUndoCreateGroupCommand::Ptr cmd = UsdUndoCreateGroupCommand::create(fItem, selection, name.string());
if (cmd) {
cmd->redo();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not that it makes much difference in your case, because the base class UndoableCommand::execute() calls redo(), but in case we ever implement UsdUndoCreateGroupCommand::execute() it would be future-proof to call cmd->execute() here.

createdItem = cmd->group();
}

return createdItem;
}

Ufe::UndoableCommand::Ptr UsdHierarchy::createGroupCmd(const Ufe::Selection& selection, const Ufe::PathComponent& name) const
{
return UsdUndoCreateGroupCommand::create(fItem, selection, name.string());
}

#endif // UFE_PREVIEW_VERSION_NUM

#endif // UFE_V2_FEATURES_AVAILABLE

} // namespace ufe
} // namespace MayaUsd
6 changes: 6 additions & 0 deletions lib/mayaUsd/ufe/UsdHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <ufe/hierarchy.h>
#include <ufe/path.h>
#include <ufe/selection.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not needed, fwd decl sufficient.


#include <mayaUsd/base/api.h>
#include <mayaUsd/ufe/UsdSceneItem.h>
Expand Down Expand Up @@ -66,8 +67,13 @@ class MAYAUSD_CORE_PUBLIC UsdHierarchy : public Ufe::Hierarchy
) override;
#endif

#if UFE_PREVIEW_VERSION_NUM < 2017
Ufe::SceneItem::Ptr createGroup(const Ufe::PathComponent& name) const override;
Ufe::Group createGroupCmd(const Ufe::PathComponent& name) const override;
#else
Ufe::SceneItem::Ptr createGroup(const Ufe::Selection& selection, const Ufe::PathComponent& name) const override;
Ufe::UndoableCommand::Ptr createGroupCmd(const Ufe::Selection& selection, const Ufe::PathComponent& name) const override;
#endif
#endif

private:
Expand Down
100 changes: 100 additions & 0 deletions lib/mayaUsd/ufe/UsdUndoAddNewPrimCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// Copyright 2019 Autodesk
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess we have to update the copyright year?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is the new file and I should have 2020 here (it's there in the .h). We don't update these dates in all files though.

//
// 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 "UsdUndoAddNewPrimCommand.h"

#include <mayaUsd/ufe/Global.h>
#include <mayaUsd/ufe/Utils.h>

namespace {

Ufe::Path appendToPath(const Ufe::Path& path, const std::string& name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is absolutely perfect, I know, and it's just a question of style, but I'm a ternary ops guy:

return (1 == path.getSegments().size()) ? path + Ufe::PathSegment(Ufe::PathComponent(name), MayaUsd::ufe::getUsdRunTimeId(), '/') : path + name;

Sorry, couldn't help myself, you can leave your code as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going to leave as-is since this is one of those chunks of code where you occasionally do want to be able to set a breakpoint to stop in a certain situation (dealing with the proxy vs. a prim).

{
Ufe::Path newUfePath;
if (1 == path.getSegments().size()) {
newUfePath = path + Ufe::PathSegment(
Ufe::PathComponent(name), MayaUsd::ufe::getUsdRunTimeId(), '/');
Copy link
Collaborator

Choose a reason for hiding this comment

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

This feels a bit awkward. I see that in places you start with a PathComponent, and convert it to a string, but here we're doing the reverse, converting the string back to a PathComponent. Why could we not stick with PathComponent throughout, if it's going to be used in a Path in the end?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I'm seeing what change you're suggesting. Where are the other PathComponents?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Here's the chain:
UsdUndoCreateGroupCommand::_name is type PathComponent

UsdUndoCreateGroupCommand::redo() calls UsdUndoAddNewPrimCommand::create(), converts to string for the call.

create() calls the UsdUndoAddNewPrimCommand, which calls appendToPath(), which takes the string and converts to a PathComponent.

Therefore, could have been a PathComponent throughout, it seems.

} else {
newUfePath = path + name;
}
return newUfePath;
}

}

MAYAUSD_NS_DEF {
namespace ufe {

UsdUndoAddNewPrimCommand::UsdUndoAddNewPrimCommand(const UsdSceneItem::Ptr& usdSceneItem,
const std::string& name, const std::string& type)
: Ufe::UndoableCommand()
{
// First get the stage from the proxy shape.
auto ufePath = usdSceneItem->path();
auto segments = ufePath.getSegments();
auto dagSegment = segments[0];
_stage = MayaUsd::ufe::getStage(Ufe::Path(dagSegment));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit-pick: can remove the MayaUsd::ufe namespace prefix, that's the namespace we're in.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Since you have a UsdSceneItem, to get the stage you can just use: usdSceneItem->prim().GetStage()

if (_stage) {
// Append the parent path and the requested name into a full ufe path.
_newUfePath = appendToPath(ufePath, name);

// Ensure the requested name is unique.
auto newPrimName = uniqueChildName(usdSceneItem, _newUfePath);

// If the name had to change then we need to update the full ufe path.
if (name != newPrimName) {
_newUfePath = appendToPath(ufePath, newPrimName);
}

// Build (and store) the usd path for the new prim with the unique name.
PXR_NS::SdfPath usdItemPath = usdSceneItem->prim().GetPath();
_primPath = usdItemPath.AppendChild(PXR_NS::TfToken(newPrimName));

// The type of prim we were asked to create.
// Note: "Def" means create typeless prim.
_primToken = (type.empty() || type == "Def") ? TfToken() : TfToken(name);
}
}

void UsdUndoAddNewPrimCommand::undo()
{
if (_stage) {
_stage->RemovePrim(_primPath);
}
}

void UsdUndoAddNewPrimCommand::redo()
{
if (_stage) {
auto prim = _stage->DefinePrim(_primPath, _primToken);
if (!prim.IsValid())
TF_RUNTIME_ERROR("Failed to create new prim type: %s", _primToken.GetText());
}
}

const Ufe::Path& UsdUndoAddNewPrimCommand::newUfePath() const
{
return _newUfePath;
}

/*static*/
UsdUndoAddNewPrimCommand::Ptr UsdUndoAddNewPrimCommand::create(const UsdSceneItem::Ptr& usdSceneItem,
const std::string& name, const std::string& type)
{
return std::make_shared<UsdUndoAddNewPrimCommand>(usdSceneItem, name, type);
}

} // namespace ufe
} // namespace MayaUsd
58 changes: 58 additions & 0 deletions lib/mayaUsd/ufe/UsdUndoAddNewPrimCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Copyright 2020 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_ADD_NEW_PRIM_COMMAND
#define USD_ADD_NEW_PRIM_COMMAND

#include <ufe/undoableCommand.h>
#include <ufe/path.h>

#include <mayaUsd/base/api.h>
#include <mayaUsd/ufe/UsdSceneItem.h>

PXR_NAMESPACE_USING_DIRECTIVE

MAYAUSD_NS_DEF {
namespace ufe {

//! \brief Undoable command for add new prim
class MAYAUSD_CORE_PUBLIC UsdUndoAddNewPrimCommand : public Ufe::UndoableCommand
{
public:
typedef std::shared_ptr<UsdUndoAddNewPrimCommand> Ptr;

UsdUndoAddNewPrimCommand(const UsdSceneItem::Ptr& usdSceneItem,
const std::string& name,
const std::string& type);

void undo() override;
void redo() override;

const Ufe::Path& newUfePath() const;

static UsdUndoAddNewPrimCommand::Ptr create(const UsdSceneItem::Ptr& usdSceneItem,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit-pick: funky indent.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit-pick: just Ptr

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I'm voting to leave as-is. All the other command classes have the full namespace listed here (so this one would look a bit odd if it was the only one that didn't), and I actually like it because there are multiple "Ptr" typedefs being used (e.g. this class has a Ptr and there's also the scene item Ptr's being used in the same functions).

Copy link
Collaborator

Choose a reason for hiding this comment

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

O.K.

const std::string& name, const std::string& type);
private:
PXR_NS::UsdStageWeakPtr _stage;
PXR_NS::SdfPath _primPath;
PXR_NS::TfToken _primToken;
Ufe::Path _newUfePath;

}; // UsdUndoAddNewPrimCommand

} // namespace ufe
} // namespace MayaUsd

#endif
Loading