-
Notifications
You must be signed in to change notification settings - Fork 127
Conversation
Cinema4d host
} | ||
for key, value in defaults.items(): | ||
if not env.get(key): | ||
env[key] = 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.
no newline at end of file
# C4D's python ships without python3.dll which pyside expects | ||
if "win" in env.get("PLAT"): | ||
new_dll_path = [ | ||
os.path.join(pype_root, "openpype", "hosts", "cinema4d", "resource", "windows", "bin") |
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.
line too long (98 > 79 characters)
env[pythonpath_key] = os.pathsep.join(new_c4dpython_path) | ||
|
||
|
||
# C4D's python ships without python3.dll which pyside expects |
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.
too many blank lines (2)
new_c4dpython_path.append(norm_path) | ||
|
||
|
||
env[pythonpath_key] = os.pathsep.join(new_c4dpython_path) |
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.
too many blank lines (2)
pythonpath_key = "PYTHONPATH" | ||
|
||
if int(_app.name) == 23: | ||
|
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.
blank line contains whitespace
print("Not Implemented") | ||
|
||
def reset_resolution(): | ||
WorkfileSettings().set_resolution() |
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.
no newline at end of file
def reset_colorspace(): | ||
print("Not Implemented") | ||
|
||
def reset_resolution(): |
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.
expected 2 blank lines, found 1
def reset_frame_range(): | ||
WorkfileSettings().set_frame_range_handles() | ||
|
||
def reset_colorspace(): |
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.
expected 2 blank lines, found 1
@@ -0,0 +1,10 @@ | |||
from .lib import WorkfileSettings | |||
|
|||
def reset_frame_range(): |
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.
expected 2 blank lines, found 1
for key, value in defaults.items(): | ||
exporter[value["id"]] = settings.get(key) or value["default"] | ||
|
||
c4d.documents.SaveDocument(doc, filepath, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, c4d.FORMAT_ABCEXPORT) |
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.
no newline at end of file
members_hierarchy = list( | ||
set( | ||
[str(x) for x in members] + \ | ||
[str(x) for x in children] + \ | ||
[str(x) for x in parents] | ||
) | ||
) |
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.
members_hierarchy = list( | |
set( | |
[str(x) for x in members] + \ | |
[str(x) for x in children] + \ | |
[str(x) for x in parents] | |
) | |
) | |
members_hierarchy = list( | |
set(str(x) for x in members + children + parents)) | |
) |
Would this be more readable?
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.
When you mentioned on Discord you're working on a draft implementation I hadn't expected you to be this far along. This really is very solid work. So, thank you from the community already!
It's a lot of code already - but I've taken a quick peek and commented some first things that stood out to me. Hopefully it's helpful.
label = "{0} ({1})".format(name, | ||
data["asset"]) |
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.
label = "{0} ({1})".format(name, | |
data["asset"]) | |
label = "{0} ({1})".format(name, data["asset"]) |
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 taking a look! Sorry about the volume of code, I did a lot of copying and pasting from Maya/Blender/Nuke hosts to figure out how to put this together so I am sure there are a few missteps, and vestigial code from the other hosts that still needs to be cleaned out. I really appreciate you taking the time!
# Collect Children - c4d.BaseObject | ||
children = [lib.ObjectPath(obj=obj) for member in members for obj in lib.walk_hierarchy(member.obj.GetDown())] |
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.
Note - I know NOTHING of Cinema4D but I had a quick glance over this page.
Wouldn't GetDown
just return the "first child" of each node? Shouldn't this be GetChildren()
?
It seems walk_hierarchy
does seem to work around that with GetNext()
- but wouldn't starting from the child only walk the hierarchy of those children. I feel the logic is a bit off somewhere.
Is it walk_hierarchy
that is also walking the siblings of the object passed into it? I wouldn't expect that myself. I would've expected it to walk down the hierarchy from the node passed in and not touch its direct siblings.
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.
Should children
include all descendants in the hierarchy or just the direct children of the object? I was collecting all children, GetChildren()
is only direct children.
I see what your saying with walk_hierarchy
not working as you would expect. There is a reason and I don't know if it is a good one. In C4D the pattern for listing most things in a project file is to get the first object, like doc.GetFirstMaterial()
or doc.GetFirstObject()
, which then requires something like:
obj = doc.GetFirstObject()
while obj:
#do stuff with obj
obj = obj.GetNext()
What I should probably do is just make a separate get_siblings()
function for anything like that, so that walk_hierarchy
operates more like os.walk
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.
Should children include all descendants in the hierarchy or just the direct children of the object? I was collecting all children, GetChildren() is only direct children.
Your assumption is correct - it should be ALL children + grandchildren.
I see what your saying with walk_hierarchy not working as you would expect. There is a reason and I don't know if it is a good one. In C4D the pattern for listing most things in a project file is to get the first object, like doc.GetFirstMaterial() or doc.GetFirstObject(), which then requires something like:
Sort of, yes. I read the code as it currently doing this:
current_node = member.obj
first_child_of_current_node = member.obj.GetDown()
all_siblings_and_its_children_and_grandchildren = walk_hierarchy(first_child_of_current_node)
Which if that is the case then functionality wise it does do as it should. I just wouldn't have expected to have to pass the first child of the obj
to walk its hierarchy.
So solely based on function name I wouldn't have expected walk_hierarchy
to also go over "siblings" of the input object but would have instead expected it to just go down, and go from there. But I can see from the C4D logic point of view how walk_hierarchy
with just the .Next()
implementation is much more generic maybe. I somehow would've expected walk_hierarchy
to first do a .GetDown()
internally so that it's really only about walking down the hierarchy and its children's siblings, etc.
# Append start frame and end frame to label if present | ||
if "frameStart" and "frameEnd" in data: | ||
|
||
# if frame range on maya set is the same as full shot range | ||
# adjust the values to match the asset data | ||
if (ctx_frame_start_handle == data["frameStart"] | ||
and ctx_frame_end_handle == data["frameEnd"]): # noqa: W503, E501 | ||
data["frameStartHandle"] = ctx_frame_start_handle | ||
data["frameEndHandle"] = ctx_frame_end_handle | ||
data["frameStart"] = ctx_frame_start | ||
data["frameEnd"] = ctx_frame_end | ||
data["handleStart"] = ctx_handle_start | ||
data["handleEnd"] = ctx_handle_end | ||
|
||
# if there are user values on start and end frame not matching | ||
# the asset, use them | ||
|
||
else: | ||
if "handles" in data: | ||
data["handleStart"] = data["handles"] | ||
data["handleEnd"] = data["handles"] | ||
else: | ||
data["handleStart"] = 0 | ||
data["handleEnd"] = 0 | ||
|
||
data["frameStartHandle"] = data["frameStart"] - data["handleStart"] # noqa: E501 | ||
data["frameEndHandle"] = data["frameEnd"] + data["handleEnd"] # noqa: E501 | ||
|
||
if "handles" in data: | ||
data.pop('handles') |
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.
FYI - This logic can probably be greatly simplified, see #3437 - even though that one is still in discussion.
ctx_frame_start = context.data['frameStart'] | ||
ctx_frame_end = context.data['frameEnd'] | ||
ctx_handle_start = context.data['handleStart'] | ||
ctx_handle_end = context.data['handleEnd'] | ||
ctx_frame_start_handle = context.data['frameStartHandle'] | ||
ctx_frame_end_handle = context.data['frameEndHandle'] | ||
|
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.
Might be removable - see comment down below about #3437
|
||
Limitations: | ||
- Does not take into account nodes connected to those | ||
within an objectSet. Extractors are assumed to export | ||
with history preserved, but this limits what they will | ||
be able to achieve and the amount of data available | ||
to validators. An additional collector could also | ||
append this input data into the instance, as we do | ||
for `pype.rig` with collect_history. |
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 coming from Maya implementation - and I'm not sure is relevant to your code.
Limitations: | |
- Does not take into account nodes connected to those | |
within an objectSet. Extractors are assumed to export | |
with history preserved, but this limits what they will | |
be able to achieve and the amount of data available | |
to validators. An additional collector could also | |
append this input data into the instance, as we do | |
for `pype.rig` with collect_history. |
That is really impressive! What I would suggest is that you'll move the creator/publishing logic to the new infrastructure we call .... the new publisher! :) I can help you with that as I am now finishing Houdini transition to that. It can probably help you with a few things (and complicate few more) but it is worth it. |
@antirotor Is there a good spot to see an example of what that should look like? |
This is the Houdini PR: #3046 And according to this PR #2896 that added documentation for the New Publisher this is the related documentation page: |
Exactly as @BigRoy listed. In the Houdini integration there is this part of code: defining common "new" Creator. Of note there is
Everything is written in the documentation BigRoy mentioned but if you have any questions, we are here for you. |
Thanks! I am going to dig into this and let you know if I hit any roadblocks. |
@ninglesby Any chance we can see some activity on this again? Would love to see this moving into the community. Let us know where we can help out. |
Hey @ninglesby friendly ping about this PR, are you able to dedicate time to it? |
@Minkiu If there's big interest on this I can try and spend some spare time on this - that is, if there are testers available. ;) |
I'm afraid we might need to close this stale PR. cinema4d would be great, but the demand is really minimal and @ninglesby seems quiet for a while. Better to put efforts into C4D for AYON if it comes to it. |
Brief description
Beginning work on a Cinema4D integration for OpenPype
Description
Additional info
This is still very much a WIP. I haven't dived to deeply into figuring out if this is allowed for licensing reasons, but I am including a python3.dll because pyside is expecting that dll and it is not shipped with C4D so including that is the only way I found to get OP gui to work with C4D.
Feature Request
Documentation (add "type: documentation" label)
No documentation yet.
Testing notes:
This was built with r26, and they just changed their versioning scheme to the year so I think technically cinema4d 2023 is a minor update to r26. It should be backward compatible to r23 but I haven't fully tested that.