-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1922 from Autodesk/boudrey/MAYA-112882/editRouter
Boudrey/maya 112882/edit router
- Loading branch information
Showing
13 changed files
with
403 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// | ||
// Copyright 2021 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 <mayaUsd/utils/editRouter.h> | ||
|
||
#include <pxr/base/tf/pyLock.h> | ||
|
||
#include <boost/python.hpp> | ||
#include <boost/python/def.hpp> | ||
|
||
#include <iostream> | ||
|
||
using namespace boost::python; | ||
|
||
namespace { | ||
|
||
class PyEditRouter : public MayaUsd::EditRouter | ||
{ | ||
public: | ||
PyEditRouter(PyObject* pyCallable) | ||
: _pyCb(pyCallable) | ||
{ | ||
} | ||
|
||
~PyEditRouter() override { } | ||
|
||
void operator()(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionary& routingData) override | ||
{ | ||
PXR_NS::TfPyLock pyLock; | ||
if (!PyCallable_Check(_pyCb)) { | ||
return; | ||
} | ||
try { | ||
boost::python::object dictObject(routingData); | ||
call<void>(_pyCb, context, dictObject); | ||
boost::python::extract<PXR_NS::VtDictionary> extractedDict(dictObject); | ||
if (extractedDict.check()) { | ||
routingData = extractedDict; | ||
} | ||
} catch (const error_already_set&) { | ||
std::cout << "Python exception raised in call() of Python callback." << std::endl; | ||
PyErr_Print(); | ||
} | ||
} | ||
|
||
private: | ||
PyObject* _pyCb; | ||
}; | ||
|
||
} // namespace | ||
|
||
void wrapEditRouter() | ||
{ | ||
// As per | ||
// https://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this | ||
// the plus (+) sign before the lambda triggers a conversion to a plain old | ||
// function pointer for the lambda, which is required for successful Boost | ||
// Python compilation of the lambda and its argument. | ||
|
||
def( | ||
"registerEditRouter", +[](const PXR_NS::TfToken& operation, PyObject* editRouter) { | ||
return MayaUsd::registerEditRouter( | ||
operation, std::make_shared<PyEditRouter>(editRouter)); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// | ||
// Copyright 2021 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 "editRouter.h" | ||
|
||
#include <pxr/base/tf/callContext.h> | ||
#include <pxr/base/tf/diagnosticLite.h> | ||
#include <pxr/base/tf/token.h> | ||
#include <pxr/usd/usd/editContext.h> | ||
#include <pxr/usd/usd/stage.h> | ||
#include <pxr/usd/usdGeom/gprim.h> | ||
|
||
#include <iostream> | ||
|
||
namespace { | ||
|
||
MayaUsd::EditRouters editRouters; | ||
|
||
void editTargetLayer(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionary& routingData) | ||
{ | ||
// We expect a prim in the context. | ||
auto found = context.find("prim"); | ||
if (found == context.end()) { | ||
return; | ||
} | ||
auto primValue = found->second; | ||
auto prim = primValue.Get<PXR_NS::UsdPrim>(); | ||
if (!prim) { | ||
return; | ||
} | ||
auto layer = prim.GetStage()->GetEditTarget().GetLayer(); | ||
routingData["layer"] = PXR_NS::VtValue(layer); | ||
} | ||
|
||
} // namespace | ||
|
||
namespace MAYAUSD_NS_DEF { | ||
|
||
EditRouter::~EditRouter() { } | ||
|
||
CxxEditRouter::~CxxEditRouter() { } | ||
|
||
void CxxEditRouter::operator()( | ||
const PXR_NS::VtDictionary& context, | ||
PXR_NS::VtDictionary& routingData) | ||
{ | ||
_cb(context, routingData); | ||
} | ||
|
||
EditRouters editRouterDefaults() | ||
{ | ||
using namespace PXR_NS; | ||
|
||
EditRouters defaultRouters; | ||
TfTokenVector defaultOperations = { TfToken("parent"), TfToken("duplicate") }; | ||
for (const auto& o : defaultOperations) { | ||
defaultRouters[o] = std::make_shared<CxxEditRouter>(editTargetLayer); | ||
} | ||
return defaultRouters; | ||
} | ||
|
||
void registerEditRouter(const PXR_NS::TfToken& operation, const EditRouter::Ptr& editRouter) | ||
{ | ||
editRouters[operation] = editRouter; | ||
} | ||
|
||
PXR_NS::SdfLayerHandle | ||
getEditRouterLayer(const PXR_NS::TfToken& operation, const PXR_NS::UsdPrim& prim) | ||
{ | ||
auto foundRouter = editRouters.find(operation); | ||
if (foundRouter == editRouters.end()) | ||
return nullptr; | ||
|
||
auto dstEditRouter = foundRouter->second; | ||
PXR_NS::VtDictionary context; | ||
PXR_NS::VtDictionary routingData; | ||
context["prim"] = PXR_NS::VtValue(prim); | ||
(*dstEditRouter)(context, routingData); | ||
// Try to retrieve the layer from the edit control data. | ||
auto found = routingData.find("layer"); | ||
if (found != routingData.end()) { | ||
if (found->second.IsHolding<std::string>()) { | ||
std::string layerName = found->second.Get<std::string>(); | ||
PXR_NS::SdfLayerRefPtr layer = prim.GetStage()->GetRootLayer()->Find(layerName); | ||
return layer; | ||
} else if (found->second.IsHolding<PXR_NS::SdfLayerHandle>()) { | ||
return found->second.Get<PXR_NS::SdfLayerHandle>(); | ||
} | ||
} | ||
return prim.GetStage()->GetEditTarget().GetLayer(); | ||
} | ||
|
||
} // namespace MAYAUSD_NS_DEF |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// | ||
// Copyright 2021 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. | ||
// | ||
#pragma once | ||
|
||
#include <mayaUsd/base/api.h> | ||
|
||
#include <pxr/base/tf/hashmap.h> | ||
#include <pxr/base/vt/dictionary.h> | ||
#include <pxr/usd/sdf/types.h> | ||
#include <pxr/usd/usd/prim.h> | ||
|
||
#include <functional> | ||
#include <memory> | ||
|
||
namespace MAYAUSD_NS_DEF { | ||
|
||
// An edit router is used to direct USD edits to their destination in the scene | ||
// graph. This may be a layer, a variant, a USD payload file, etc. | ||
class MAYAUSD_CORE_PUBLIC EditRouter | ||
{ | ||
public: | ||
typedef std::shared_ptr<EditRouter> Ptr; | ||
|
||
virtual ~EditRouter(); | ||
|
||
// Compute the routing data. The context is immutable, and is input to | ||
// the computation of the routing data. Routing data may be initialized, | ||
// so that acceptable defaults can be left unchanged. | ||
virtual void operator()(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionary& routingData) | ||
= 0; | ||
}; | ||
|
||
// Wrap an argument edit router callback for storage in the edit router map. | ||
class MAYAUSD_CORE_PUBLIC CxxEditRouter : public EditRouter | ||
{ | ||
public: | ||
using EditRouterCb = std::function< | ||
void(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionary& routingData)>; | ||
|
||
CxxEditRouter(EditRouterCb cb) | ||
: _cb(cb) | ||
{ | ||
} | ||
|
||
~CxxEditRouter() override; | ||
|
||
void | ||
operator()(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionary& routingData) override; | ||
|
||
private: | ||
EditRouterCb _cb; | ||
}; | ||
|
||
using EditRouters | ||
= PXR_NS::TfHashMap<PXR_NS::TfToken, EditRouter::Ptr, PXR_NS::TfToken::HashFunctor>; | ||
|
||
MAYAUSD_CORE_PUBLIC | ||
PXR_NS::SdfLayerHandle | ||
getEditRouterLayer(const PXR_NS::TfToken& operation, const PXR_NS::UsdPrim& prim); | ||
|
||
// Register an edit router for the argument operation. | ||
MAYAUSD_CORE_PUBLIC | ||
void registerEditRouter(const PXR_NS::TfToken& operation, const EditRouter::Ptr& editRouter); | ||
|
||
// Return built-in default edit routers. | ||
EditRouters editRouterDefaults(); | ||
|
||
} // namespace MAYAUSD_NS_DEF |
Oops, something went wrong.