-
Notifications
You must be signed in to change notification settings - Fork 126
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
Maya: Camera extra data - additional fix for #3304 #3386
Maya: Camera extra data - additional fix for #3304 #3386
Conversation
…2_maya-camera-content-validation
Task linked: OP-3302 Camera with proxy geometry |
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.
for cam, (attr, value) in itertools.product(cmds.ls( | ||
baked_camera_shapes, type="camera", dag=True, | ||
shapes=True, long=True): | ||
attrs = {"backgroundColorR": 0.0, | ||
"backgroundColorG": 0.0, | ||
"backgroundColorB": 0.0, | ||
"overscan": 1.0} | ||
for attr, value in attrs.items(): | ||
plug = "{0}.{1}".format(cam, attr) | ||
unlock(plug) | ||
cmds.setAttr(plug, value) | ||
shapes=True, long=True), attrs.items()): | ||
# the above call still pull in shapes that are not | ||
# cameras, so we filter them out here | ||
if cmds.nodeType(cam) != "camera": | ||
continue | ||
plug = "{0}.{1}".format(cam, attr) | ||
unlock(plug) | ||
cmds.setAttr(plug, value) |
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.
Is this really a sensible change?
- The code is much harder to read.
- Not sure why we need to check whether the type is camera if we're already filtering to camera in the
ls
query. Plus we're now doing that per attribute, not just per camera (so a lot of potential queries?)
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.
that check there was because I've overlooked the shape
flag and was wondering why the hell I still get other shapes than camera. Apart from that, the code is maybe harder to read but is getting rid of one loop and re-setting of attrs
that is constant in each iteration.
for member in members: | ||
transform = cmds.listRelatives( | ||
member, parent=True, fullPath=True)[0] | ||
member, parent=True, fullPath=True) | ||
transform = transform[0] if transform else member |
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.
Not entirely sure but this is something to be aware of. Solely looking at this code if a camera instance previously contained a parent group of the camera instead of the camera itself the old logic would still select the 'camera' for export.
I suspect this will now change the behavior for older camera instances that originally would not include the parent hierarchy.
group1/group2/camera
Would previously export as
camera
Even when group1
is in the camera instance (unless something else invalidates that?)
I suspect after this change the export is now:
group1/group2/camera
This is now behaving as it was before - if baked, camera will be out of its hierarchy. It has one limitation and that is if the hierarchy of camera contains geometry that we want out too, it will fail on parenting/ancestor relationship but that is clear limitation I can live with. |
member, ad=True, fullPath=True) or [] | ||
# skip hierarchy if it contains only camera | ||
# `member_content` will contain camera + its parents | ||
if camera in member_content \ |
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.
Please do not do a lookup per member whether the camera is in member_content while it is a set. This could be very slow, right? Should this be a set
?
and len(member_content) == len(camera.split("|")) - 2
What's that trying to solve? This looks like an odd comparison to me.
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.
What this is trying to achieve is to allow situations where you have camera inside some hierarchy and at the same time handle cases where you have hierarchy with camera AND something else.
alice_GRP
|---> bob_GRP
| \---> camera1_CAM
\---> box_GEO
in that case you would expect alembic with:
camera1_CAM
alice_GRP
\---> box_GEO
but that will fail because alice_GRP
and camera1_CAM
have parent relationship.
So what it does is that it gets all descendants of the member and check if the count of them is exactly the same as the path to the camera (minus 2 for the camera transform and shape).
Camera is |alice_GRP|bob_GRP|camera1_CAM|camera1_CAMShape
and all descendants for member |alice_GRP
are ["|alice_GRP", "|alice_GRP|bob_GRP"]
if count of member_content
is higher, it means there are more things there than camera. I think there should be warning logged before continue
.
This could be very slow, right?
actually Maya is pretty fast for that one. I've just ran some benchmarks and for 1000 calls I get something aroung ~0.02 sec
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.
Why wouldn't we just check whether this:
descendents = cmds.listRelatives(member, allDescendents=True, fullPath=True) or []
shapes = cmds.ls(descendents, shapes=True, noIntermediate=True, long=True)
cameras = cmds.ls(shapes, type="camera", long=True)
if set(shapes) - set(cameras):
# There are other shapes than just cameras present
...
Bonus is that this would ignore empty transforms/groups and intermediate shapes. We could also e.g. ignore deformers as well that might be parented under the camera for who knows what reason (which wouldn't end up in an Alembic anyway so we can just skip them too, right?)
I have a feeling we're overthinking or over-engineering this concept somehow. The fact that this starts behaving differently in a certain edge also feels less consistent than we'd like for a publish. No?
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.
damn you are right. Why is it the sets always eludes me even if the are the easiest solution.
# Fix PLN-178: Don't allow background color to be non-black | ||
for cam in cmds.ls( | ||
for cam, (attr, value) in itertools.product(cmds.ls( | ||
baked_camera_shapes, type="camera", dag=True, | ||
shapes=True, long=True): | ||
attrs = {"backgroundColorR": 0.0, | ||
"backgroundColorG": 0.0, | ||
"backgroundColorB": 0.0, | ||
"overscan": 1.0} | ||
for attr, value in attrs.items(): | ||
plug = "{0}.{1}".format(cam, attr) | ||
unlock(plug) | ||
cmds.setAttr(plug, value) | ||
long=True), attrs.items()): | ||
plug = "{0}.{1}".format(cam, attr) | ||
unlock(plug) | ||
cmds.setAttr(plug, value) |
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.
I know it's functionally the same - but do we feel itertools.product
is really that much more readable then the nested for loop? I'm fine with either but somehow I have a harder time reading this new code.
Fix
This is adding forgotten commits to already merged PR #3304. It solves issues of parented geometry inside camera instance.
Testing
Try to publish camera with parented geometry. Validator should trigger.