Skip to content

Commit

Permalink
Merge pull request #2967 from Autodesk/hewettc/LOOKDEVX-1112/backdrop…
Browse files Browse the repository at this point in the history
…-squashed

Added size functions in UINodeGraphNode
  • Loading branch information
seando-adsk authored Mar 30, 2023
2 parents c9143f2 + 187acf5 commit cd1f191
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 70 deletions.
9 changes: 9 additions & 0 deletions cmake/modules/FindUFE.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,12 @@ if(UFE_INCLUDE_DIR AND EXISTS "${UFE_INCLUDE_DIR}/ufe/trie.h")
message(STATUS "Maya has UFE TrieNode childrenComponents accessor")
endif()
endif()

set(UFE_UINODEGRAPHNODE_HAS_SIZE FALSE CACHE INTERNAL "ufeUINodeGraphNodeHasSize")
if(UFE_INCLUDE_DIR AND EXISTS "${UFE_INCLUDE_DIR}/ufe/uiNodeGraphNode.h")
file(STRINGS ${UFE_INCLUDE_DIR}/ufe/uiNodeGraphNode.h UFE_HAS_API REGEX "getSize")
if(UFE_HAS_API)
set(UFE_UINODEGRAPHNODE_HAS_SIZE TRUE CACHE INTERNAL "ufeUINodeGraphNodeHasSize")
message(STATUS "Maya has UFE UINodeGraphNode size interface")
endif()
endif()
7 changes: 7 additions & 0 deletions lib/mayaUsd/ufe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ if (UFE_SCENE_SEGMENT_SUPPORT)
)
endif()

if (UFE_UINODEGRAPHNODE_HAS_SIZE)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
UFE_UINODEGRAPHNODE_HAS_SIZE=1
)
endif()

if (v4_BatchOps IN_LIST UFE_PREVIEW_FEATURES)
message(STATUS "UFE_PREVIEW has V4 BatchOps support")
target_sources(${PROJECT_NAME}
Expand Down
109 changes: 60 additions & 49 deletions lib/mayaUsd/ufe/UsdUINodeGraphNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,41 @@
namespace MAYAUSD_NS_DEF {
namespace ufe {

class SetPositionCommand : public Ufe::UndoableCommand
UsdUINodeGraphNode::SetPosOrSizeCommand::SetPosOrSizeCommand(
CoordType coordType,
const PXR_NS::UsdPrim& prim,
const Ufe::Vector2f& newValue)
: _coordType(coordType)
, _stage(prim.GetStage())
, _primPath(prim.GetPath())
, _newValue(PXR_NS::GfVec2f(newValue.x(), newValue.y()))
{
public:
SetPositionCommand(const PXR_NS::UsdPrim& prim, const Ufe::Vector2f& newPos)
: Ufe::UndoableCommand()
, _stage(prim.GetStage())
, _primPath(prim.GetPath())
, _newPos(PXR_NS::GfVec2f(newPos.x(), newPos.y()))
{
}
}

void execute() override
{
PXR_NAMESPACE_USING_DIRECTIVE
if (_stage) {
const UsdPrim prim = _stage->GetPrimAtPath(_primPath);
if (!prim.HasAPI<UsdUINodeGraphNodeAPI>()) {
UsdUINodeGraphNodeAPI::Apply(prim);
}
if (prim.HasAPI<UsdUINodeGraphNodeAPI>()) {
UsdUINodeGraphNodeAPI posApi(prim);
TF_VERIFY(posApi);
UsdAttribute attr = posApi.GetPosAttr();
if (!attr) {
attr = posApi.CreatePosAttr();
}
attr.Set(_newPos);
void UsdUINodeGraphNode::SetPosOrSizeCommand::executeImplementation()
{
PXR_NAMESPACE_USING_DIRECTIVE
if (_stage) {
const UsdPrim prim = _stage->GetPrimAtPath(_primPath);
if (!prim.HasAPI<UsdUINodeGraphNodeAPI>()) {
UsdUINodeGraphNodeAPI::Apply(prim);
}
if (prim.HasAPI<UsdUINodeGraphNodeAPI>()) {
UsdUINodeGraphNodeAPI posApi(prim);
TF_VERIFY(posApi);
UsdAttribute attr
= _coordType == CoordType::Position ? posApi.GetPosAttr() : posApi.GetSizeAttr();
if (!attr) {
attr = _coordType == CoordType::Position ? posApi.CreatePosAttr()
: posApi.CreateSizeAttr();
}
attr.Set(_newValue);
}
}

void undo() override { }
void redo() override { }

private:
const PXR_NS::UsdStageWeakPtr _stage;
const PXR_NS::SdfPath _primPath;
const PXR_NS::VtValue _newPos;
};
}

UsdUINodeGraphNode::UsdUINodeGraphNode(const UsdSceneItem::Ptr& item)
: Ufe::UINodeGraphNode()
, fItem(item)
: fItem(item)
{
}

Expand All @@ -68,37 +60,56 @@ UsdUINodeGraphNode::Ptr UsdUINodeGraphNode::create(const UsdSceneItem::Ptr& item

Ufe::SceneItem::Ptr UsdUINodeGraphNode::sceneItem() const { return fItem; }

bool UsdUINodeGraphNode::hasPosition() const
bool UsdUINodeGraphNode::hasPosition() const { return hasPosOrSize(CoordType::Position); }

Ufe::Vector2f UsdUINodeGraphNode::getPosition() const { return getPosOrSize(CoordType::Position); }

Ufe::UndoableCommand::Ptr UsdUINodeGraphNode::setPositionCmd(const Ufe::Vector2f& pos)
{
return std::make_shared<SetPosOrSizeCommand>(
CoordType::Position, fItem ? fItem->prim() : PXR_NS::UsdPrim(), pos);
}

#ifdef UFE_UINODEGRAPHNODE_HAS_SIZE
bool UsdUINodeGraphNode::hasSize() const { return hasPosOrSize(CoordType::Size); }

Ufe::Vector2f UsdUINodeGraphNode::getSize() const { return getPosOrSize(CoordType::Size); }

Ufe::UndoableCommand::Ptr UsdUINodeGraphNode::setSizeCmd(const Ufe::Vector2f& size)
{
return std::make_shared<SetPosOrSizeCommand>(
CoordType::Size, fItem ? fItem->prim() : PXR_NS::UsdPrim(), size);
}
#endif

bool UsdUINodeGraphNode::hasPosOrSize(CoordType coordType) const
{
PXR_NAMESPACE_USING_DIRECTIVE
const UsdPrim prim = fItem->prim();
UsdUINodeGraphNodeAPI posApi(prim);
if (!posApi) {
return false;
}
UsdAttribute attr = posApi.GetPosAttr();
UsdAttribute attr
= coordType == CoordType::Position ? posApi.GetPosAttr() : posApi.GetSizeAttr();
return attr.IsValid();
}

Ufe::Vector2f UsdUINodeGraphNode::getPosition() const
Ufe::Vector2f UsdUINodeGraphNode::getPosOrSize(CoordType coordType) const
{
if (hasPosition()) {
if (hasPosOrSize(coordType)) {
const PXR_NS::UsdPrim prim = fItem->prim();
const PXR_NS::UsdUINodeGraphNodeAPI posApi(prim);
const PXR_NS::UsdAttribute attr = posApi.GetPosAttr();
PXR_NS::VtValue v;
const PXR_NS::UsdAttribute attr
= coordType == CoordType::Position ? posApi.GetPosAttr() : posApi.GetSizeAttr();
PXR_NS::VtValue v;
attr.Get(&v);
const PXR_NS::GfVec2f pos = v.Get<PXR_NS::GfVec2f>();
return Ufe::Vector2f(pos[0], pos[1]);
const PXR_NS::GfVec2f val = v.Get<PXR_NS::GfVec2f>();
return Ufe::Vector2f(val[0], val[1]);
} else {
return Ufe::Vector2f(0.0f, 0.0f);
}
}

Ufe::UndoableCommand::Ptr UsdUINodeGraphNode::setPositionCmd(const Ufe::Vector2f& pos)
{
return std::make_shared<SetPositionCommand>(fItem ? fItem->prim() : PXR_NS::UsdPrim(), pos);
}

} // namespace ufe
} // namespace MAYAUSD_NS_DEF
40 changes: 39 additions & 1 deletion lib/mayaUsd/ufe/UsdUINodeGraphNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@
#include "UsdSceneItem.h"

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

#include <ufe/uiNodeGraphNode.h>

namespace MAYAUSD_NS_DEF {
namespace ufe {

//! \brief Implementation of Ufe::UINodeGraphNode interface for USD objects.
class MAYAUSD_CORE_PUBLIC UsdUINodeGraphNode : public Ufe::UINodeGraphNode
class MAYAUSD_CORE_PUBLIC UsdUINodeGraphNode
: public
#ifdef UFE_V4_1_FEATURES_AVAILABLE
Ufe::UINodeGraphNode_v4_1
#else
Ufe::UINodeGraphNode
#endif
{
public:
typedef std::shared_ptr<UsdUINodeGraphNode> Ptr;
Expand All @@ -42,9 +49,40 @@ class MAYAUSD_CORE_PUBLIC UsdUINodeGraphNode : public Ufe::UINodeGraphNode
bool hasPosition() const override;
Ufe::Vector2f getPosition() const override;
Ufe::UndoableCommand::Ptr setPositionCmd(const Ufe::Vector2f& pos) override;
#ifdef UFE_UINODEGRAPHNODE_HAS_SIZE
bool hasSize() const override;
Ufe::Vector2f getSize() const override;
Ufe::UndoableCommand::Ptr setSizeCmd(const Ufe::Vector2f& size) override;
#endif

private:
enum class CoordType
{
Position,
Size
};

class SetPosOrSizeCommand : public UsdUndoableCommand<Ufe::UndoableCommand>
{
public:
SetPosOrSizeCommand(
CoordType coordType,
const PXR_NS::UsdPrim& prim,
const Ufe::Vector2f& newValue);

void executeImplementation() override;

private:
const CoordType _coordType;
const PXR_NS::UsdStageWeakPtr _stage;
const PXR_NS::SdfPath _primPath;
const PXR_NS::VtValue _newValue;
};

UsdSceneItem::Ptr fItem;

bool hasPosOrSize(CoordType coordType) const;
Ufe::Vector2f getPosOrSize(CoordType coordType) const;
};

} // namespace ufe
Expand Down
65 changes: 45 additions & 20 deletions test/lib/ufe/testUINodeGraphNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,38 +56,63 @@ def setUp(self):
# Clear selection to start off
cmds.select(clear=True)

def testUIInfo(self):
ball3Path = ufe.PathString.path('|transform1|proxyShape1,/Ball_set/Props/Ball_3')
ball3SceneItem = ufe.Hierarchy.createItem(ball3Path)

initialUpdateCount = cmds.getAttr('|transform1|proxyShape1.updateId')
initialResyncCount = cmds.getAttr('|transform1|proxyShape1.resyncId')

uiNodeGraphNode = ufe.UINodeGraphNode.uiNodeGraphNode(ball3SceneItem)

self.assertFalse(uiNodeGraphNode.hasPosition())
pos0 = uiNodeGraphNode.getPosition()
# Helper to avoid copy-pasting the entire test
def doPosAndSizeTests(self, hasFunc, setFunc, getFunc, cmdFunc):
# Test hasFunc and getFunc
self.assertFalse(hasFunc())
pos0 = getFunc()
self.assertEqual(pos0.x(), 0)
self.assertEqual(pos0.y(), 0)

# Test setFunc with vector
pos1 = ufe.Vector2f(10, 20)
uiNodeGraphNode.setPosition(pos1)
self.assertTrue(uiNodeGraphNode.hasPosition())
pos2 = uiNodeGraphNode.getPosition()
setFunc(pos1)
self.assertTrue(hasFunc())
pos2 = getFunc()
self.assertEqual(pos1.x(), pos2.x())
self.assertEqual(pos1.y(), pos2.y())
uiNodeGraphNode.setPosition(13, 41)
self.assertTrue(uiNodeGraphNode.hasPosition())
pos3 = uiNodeGraphNode.getPosition()

# Test setFunc with scalars
setFunc(13, 41)
self.assertTrue(hasFunc())
pos3 = getFunc()
self.assertEqual(pos3.x(), 13)
self.assertEqual(pos3.y(), 41)

# Test cmdFunc
pos4 = ufe.Vector2f(21, 20)
cmd = uiNodeGraphNode.setPositionCmd(pos4)
cmd = cmdFunc(pos4)
cmd.execute()
self.assertTrue(uiNodeGraphNode.hasPosition())
pos5 = uiNodeGraphNode.getPosition()
self.assertTrue(hasFunc())
pos5 = getFunc()
self.assertEqual(pos4.x(), pos5.x())
self.assertEqual(pos4.y(), pos5.y())

def testPosition(self):
ball3Path = ufe.PathString.path('|transform1|proxyShape1,/Ball_set/Props/Ball_3')
ball3SceneItem = ufe.Hierarchy.createItem(ball3Path)

initialUpdateCount = cmds.getAttr('|transform1|proxyShape1.updateId')
initialResyncCount = cmds.getAttr('|transform1|proxyShape1.resyncId')

uiNodeGraphNode = ufe.UINodeGraphNode.uiNodeGraphNode(ball3SceneItem)
self.doPosAndSizeTests(uiNodeGraphNode.hasPosition, uiNodeGraphNode.setPosition,
uiNodeGraphNode.getPosition, uiNodeGraphNode.setPositionCmd)

@unittest.skipIf(os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') < '4100',
'Size interface only available in Ufe preview version greater equal to 4.0.100, or 0.5.0.')
def testSize(self):
ball3Path = ufe.PathString.path('|transform1|proxyShape1,/Ball_set/Props/Ball_3')
ball3SceneItem = ufe.Hierarchy.createItem(ball3Path)

if(hasattr(ufe, "UINodeGraphNode_v4_1")):
uiNodeGraphNode = ufe.UINodeGraphNode_v4_1.uiNodeGraphNode(ball3SceneItem)
else:
uiNodeGraphNode = ufe.UINodeGraphNode.uiNodeGraphNode(ball3SceneItem)

self.doPosAndSizeTests(uiNodeGraphNode.hasSize, uiNodeGraphNode.setSize,
uiNodeGraphNode.getSize, uiNodeGraphNode.setSizeCmd)

# None of these changes should force a render refresh:
self.assertEqual(initialUpdateCount, cmds.getAttr('|transform1|proxyShape1.updateId'))
self.assertEqual(initialResyncCount, cmds.getAttr('|transform1|proxyShape1.resyncId'))
Expand Down

0 comments on commit cd1f191

Please sign in to comment.