-
Notifications
You must be signed in to change notification settings - Fork 203
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
add support for manipulating point instances via UFE #1241
add support for manipulating point instances via UFE #1241
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good to me from a code structure point of view! Left a few comments / questions, and there is UFE_V2 conditional compilation work that needs a bit of clarification, but this is close to being ready, in my opinion.
I cannot tell at a glance why rotation and scaling manipulation are causing trouble. I have had trouble in the past using matrix decomposition code from Pixar, and had to change to Maya API matrix decomposition to get proper manipulation --- see
// Decompose new matrix to extract TRS. Neither GfMatrix4d::Factor |
Possibly something to try later on; I don't feel we should delay converting this from a draft pull request to a pull request because of this issue.
@@ -46,6 +47,10 @@ Ufe::Transform3d::Ptr UsdTransform3dHandler::transform3d(const Ufe::SceneItem::P | |||
assert(usdItem); | |||
#endif | |||
|
|||
if (usdItem->isPointInstance()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the old Transform3d handling scheme, correct? I see you've adjusted the chain of responsibility for the new scheme in adsk/plugin/plugin.cpp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, yeah. My main concern here was if you have multiple point instances for the same PointInstancer
selected, we don't want to fall through to the "usual" Transform3d
which may result in many objects that all try to treat their item as a discrete prim and attempt to create the same xformOps on the PointInstancer
.
Do you think it's clearer or more safe to just not support point instances in this old handler? Maybe we're planning to get rid of it soon anyway?
public: | ||
using Ptr = std::shared_ptr<UsdPointInstanceUndoableCommandBase>; | ||
|
||
#ifdef UFE_V2_FEATURES_AVAILABLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If UsdTransform3dPointInstance depends on UFE_V2, does it make sense to conditionally compile in UsdPointInstanceUndoableCommands for UFE_V1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I admittedly have only been working with this code against PR 122, so there's an excellent chance this doesn't even build successfully against Maya 2020 as it is right now.
I think my intent was to gracefully ignore attempts to manipulate point instances for UFE v1. The way things are currently setup, it should be possible in UFE v1 to have UFE selections that include scene items representing point instances, even though point instance selection in the viewport is UFE v2 only. In that case, I was aiming for requests to manipulate point instance items in UFE v1 basically becoming no-ops. That was why I had the modifiers and the commands included in the CMakeLists.txt for both UFE v1 and UFE v2.
So I think what I actually have to do is ensure that all of the new files here are compiled for both UFE versions. Does all of this sound right/reasonable to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If UFE v1 is intended to be a no-op, then it seems to me that you could just return null pointers when you're asked for commands. That way, you wouldn't need to compile commands against UFE v1 --- and if the commands are the only clients of the modifiers, then the modifiers wouldn't need to be compiled against UFE v1 either. Does this align with your thinking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does, thanks! In the most recent changes, UsdPointInstanceUndoableCommands.h
is only included for UFE v2.
I ended up leaving the modifiers in for both versions of UFE, since strictly speaking there's nothing in them that requires v2, so they could theoretically get used for non-Transform3d authoring operations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback, @ppt-adsk! All great notes.
I'll see if I can "finish" this by addressing what you've noted so far, and add at least a few simple tests for the new functionality. I'll then convert it to a non-draft PR.
I'm a little concerned that the unit tests wouldn't actually cover the issues I was seeing when interactively pulling on the manipulator handles, since just doing cmds.move()
, cmds.rotate()
, etc. seem to work. Thanks for noting the issues you saw with the USD-side Decompose()
though. I can give the Maya-side versions of that a try and see whether that makes a difference.
I'm also still a little concerned about how performance scales with having a Transform3d
per point instance scene item and the the single-element modifications that each of those are doing. With the API that's currently available on both the USD side and the UFE side, I'm not sure there's much of a way around that at the moment.
public: | ||
using Ptr = std::shared_ptr<UsdPointInstanceUndoableCommandBase>; | ||
|
||
#ifdef UFE_V2_FEATURES_AVAILABLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I admittedly have only been working with this code against PR 122, so there's an excellent chance this doesn't even build successfully against Maya 2020 as it is right now.
I think my intent was to gracefully ignore attempts to manipulate point instances for UFE v1. The way things are currently setup, it should be possible in UFE v1 to have UFE selections that include scene items representing point instances, even though point instance selection in the viewport is UFE v2 only. In that case, I was aiming for requests to manipulate point instance items in UFE v1 basically becoming no-ops. That was why I had the modifiers and the commands included in the CMakeLists.txt for both UFE v1 and UFE v2.
So I think what I actually have to do is ensure that all of the new files here are compiled for both UFE versions. Does all of this sound right/reasonable to you?
@@ -46,6 +47,10 @@ Ufe::Transform3d::Ptr UsdTransform3dHandler::transform3d(const Ufe::SceneItem::P | |||
assert(usdItem); | |||
#endif | |||
|
|||
if (usdItem->isPointInstance()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, yeah. My main concern here was if you have multiple point instances for the same PointInstancer
selected, we don't want to fall through to the "usual" Transform3d
which may result in many objects that all try to treat their item as a discrete prim and attempt to create the same xformOps on the PointInstancer
.
Do you think it's clearer or more safe to just not support point instances in this old handler? Maybe we're planning to get rid of it soon anyway?
…tInstancers This adds a UsdPointInstanceModifierBase class which will be specialized to create modifiers for the "positions", "orientations", and "scales" attributes of PointInstancer prims. Derived classes of this base class should implement the functions to directly get and create the USD attribute on the PointInstancer (typically with a call to UsdGeomPointInstancer::Get...Attr() and UsdGeomPointInstancer::Create...Attr(), respectively), functions to convert values between USD and UFE types, and a function to retrieve the default value in the USD type.
090a33e
to
41db66b
Compare
I got some great notes on this offline from @kxl-adsk and @ppt-adsk, so the newly pushed changes here seem to resolve all of the issues I was previously seeing. There were two important changes necessary:
I still need to validate this against UFE v1 and then finish up the unit tests, but it looks to be in much better shape now. Should hopefully be ready to convert this to a regular pull request soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notification scheme is the more troublesome part, but at least we have correctness, if not performance :) Perhaps given the fairly urgent time constraints this is sufficient, and we can move to creating a test and converting this draft to an actual pull request?
I'm still hopeful that we can provide a no-op implementation of the point instancer Transform3d for UFE v1 (i.e. Maya 2020) by returning null pointers instead of compiling actual code --- please set me straight on this if I've misunderstood.
…sponse to USD notices When individual point instances are manipulated, the change is represented in USD as an update to the "positions", "orientations", or "scales" array attribute(s) on the PointInstancer prim that generated the point instance. Unfortunately though, there is no way for us to know which point instance(s) were actually affected based on the USD change notification. This means that we have to assume that *all* of the PointInstancer prim's instances may have been affected. We therefore need to construct UFE paths for every instance and issue a notification for each one.
…dler Point instance manipulation using the older UsdTransform3dHandler is only supported with UFE v2. Otherwise, we disallow any manipulation for point instance scene items.
41db66b
to
8c9a659
Compare
I converted this to a regular PR, as I believe what we've got now is functionally correct and the major performance concerns we can currently tackle have been addressed. Tests are still missing, but I'll append another commit for that soon. Thanks again @ppt-adsk and @kxl-adsk for all of your help with this! |
And now with tests in e4d1e20. Kicking off a preflight run. Thanks again! |
Hopefully addressed the preflight build failures with bf4cbb2. I failed to notice that |
The range() function returns lists in Python 2 which can be added together with the '+' operator, but that's not the case in Python 3.
There was one more remaining issue in the unit test when running with Python 3 which was addressed in d504519. Other than that, I think the remaining preflight failures are the spurious kind we've seen before. |
I also run the remaining set of tests. All that is left is the review and we can merge it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good. Thank you @mattyjams !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work Matt! Thanks for sticking with this and bringing it over the finish line.
Agree with Matt, the single failing Maya 2020 Windows python 2 test run appears to be build pipeline related, all tests pass. |
I've been having trouble finding the time to root out the remaining issues with point instance manipulation, so I wanted to just post what I've got so far. Feel free to review (read: ridicule) whenever you have a chance. :)
At a high level, this probably most closely aligns with the
XformCommonAPI
Transform3d
implementation where instead of authoring translation, rotation, and scale values to xformOps dedicated to those operations, we author the values at the appropriate index in thePointInstancer
prim'spositions
,orientations
, andscales
array attributes instead.At the bottom, there is a
UsdPointInstanceModifierBase
class that handles most of the work of getting and setting individual element values in aPointInstancer
prim's array attributes. This is then specialized into concrete subclasses for position, orientation, and scale modifiers.Above that, there are a set of undoable commands that use the modifiers for redo'ing and undo'ing their respective operations.
There's then a
UsdTransform3dPointInstance
subclass ofUfe::Transform3d
that creates commands of the appropriate type, and manages getting a point instance's current translation, rotation, and scale. It also supports querying the inclusive and exclusive matrices of an instance, and setting the instance's matrix (non-interactively).One wrinkle is that for rotation, Maya/UFE speaks in terms of Euler angles while the
PointInstancer
schema stores theorientations
attribute as quaternions (GfQuath
). I have an (admittedly ham-handed) conversion for that in the orientation modifier, but it makes for some pretty jittery manipulation as you drag the handles, and I don't think it's actually working correctly when multiple manipulations are strung together.The scale manipulator seems to work at least for the initial manipulation, but I'm seeing an odd issue when pulling on one handle then pulling on another where the second pull often scales along both axes rather than only along the second handle's axis.
The position manipulator luckily seems to be working correctly though, so at least that seems to be a win.
I'm hopeful that the things that aren't working are just small mistakes in my implementation stemming from unfamiliarity with the interface. Curious to hear what you all think!