Leaderboard
Popular Content
Showing content with the highest reputation on 05/17/2021 in all areas
-
LAB Golf Spot May 2021 Particularly rewarding project this one - modelling initially, then over to my good buddy KC for some Octane rendering, then back to me for the musics...2 points
-
Hi everyone! My name is Bendik. I'm working as a motion designer at a design/branding agency in Oslo, Norway. I started my career as a graphic designer and have extensive knowledge of the Adobe Suite. My main specialty now is motion design and 2D animation. As a step to expand my horizon I have started familiarizing myself with C4D and have used it sporadically over the past three years. I've mainly learnt about different simulations, MoGraph, compositing and rendering using Redshift. And now I'm trying to learn modelling. I've familiarized myself with the different types of modelling: parametric, spline and polygonal modelling, and find polygonal modelling the most challenging – especially planning out my process to maintain a clean mesh. To begin with I'll probably ask more questions than I answer, but I'll hopefully be able to contribute with what I know. Looking forward to become a helpful member of this community! Thank you all!1 point
-
I think this could be a real-time effect without the use of an AI. What makes it more "real" is the occlusion of detail and making the lighting less saturated. This is an effect that relies on how we are used to see the real world through a dashboard camera. It's not that the AI makes the footage more real but out perceptive expectations of this kind of footage. For me it looks like a late 90's dashboard camera. In other words it looks like a "real dashboard camera footage". The only thing that AI done really good (in my opinion) and can't be faked with post-effects is the removal of the road erosions (but I consider this an artistic intervention because the AI was dependent on the training footage which contained only good looking german roads, if Rockstar wanted smooth roads it wouldn't put so much effort on road details) So if anyone has the knowledge and equipment please post a small experimental footage edited with AfterEffects with the following setting : The output video resolution must be half of the input. Add a LUT or colour filter with reduced saturation and a shift towards green (like the MATRIX trilogy) Optionally add a smart blur or slight softness or a lot of antialiasing.1 point
-
1 point
-
Hi @Robert Krawczyk, node iteration is a bit of a hornet's nest in the Cinema 4D SDK, because although it might look like just a "trivial" graph walk, it can become quite complex due to all the corner cases that lurk in the depth of how Cinema 4D does organize its scene graph. And graph walks are also often not trivial in itself when one has to meet certain conditions like starting at an arbitrary point which cannot be "overshot" or having crazy requirements like not producing stack overflows 😉 We are aware of the problem at the SDK-Team and have it on our bucket list, i.e., want to provide an interface for it at some point. But for now, it must be done manually. Your problem has two components: Finding all Xpresso tags in a scene and iterating over all their nodes. For the latter GetDown()/Next() were the correct approach in principal, but the devil is in the detail here, one can get easily lost in these graphs. The solution provided by @JED has certainly its strengths in its simplicity, but it will not yield any nodes that are within a group node. The solution provided below uses a more abstract approach, which allows one to use it for example to also retrieve all the Xpresso tags in the scene. In practice it would be nice if we already had an node iteration interface in the SDK for the classic API, but currently we do not. My example provides a simple version, tailored to the specific case. Which can be treated as a black box if one feels uncomfortable with the code. The core logic of what you want to do, is then only this relatively accessible bit of code: # We iterate over all Xpresso tags in the document. We pass in the first # object in the scene and specify that we are only interested in nodes of # type c4d.Texpresso (Xpresso tags). for xpressoTag in NodeIterator(doc.GetFirstObject(), c4d.Texpresso): # Print out some stuff about the currently yielded Xpresso tag. name, nid = xpressoTag.GetName(), id(xpressoTag) print(f"The Xpresso tag {name} at {nid} has the nodes:") # Get its master node and root node in the Xpresso graph. masterNode = xpressoTag.GetNodeMaster() root = masterNode.GetRoot() # And iterate over all nodes in that root node. for xpressoNode in NodeIterator(root): print(f"\t{xpressoNode}") If ran on a scene, it looks like this: Cheers, Ferdinand The full code: """Example for iterating over all Xpresso nodes in a scene. Node iteration can be quite a complex topic in Cinema 4D due to the many graph relations that are contained in a document and the problems that arise from recursive solutions for the problem - stack overflows or in Python the safety measures of Python preventing them. We have this topic on our bucket list in the SDK-Team, but for now one has to approach it with self-provided solutions. This is an example pattern for a node iterator (which does not take caches into account). One can throw it at any kind of GeListNode and it will yield in a stack-safe manner all next-siblings and descendants of a node. How this iteration is carried out (depth or breadth first), to include any kind of siblings, not just next-siblings, to include also ancestors and many things more could be done differently. This pattern is tailored relatively closely to what the topic demanded. A more versatile solution would have to be provided in the SDK. """ import c4d # This is a node iteration implementation. To a certain degree this can be # treated as a black box and does not have to be understood. This will # however change when one wants to include other use-case scenarios for which # one would have to modify it. def NodeIterator(node, types=None): """An iterator for a GeListNode node graph with optional filtering. Will yield all downward siblings and all descendants of a node. Will not yield any ancestors of the node. Is stack overflow (prevention) safe due to being truly iterative. Alsob provides a filter mechanism which accepts an ineteger type symbol filter for the yielded nodes. Args: node (c4d.GeListNode): The starting node for which to yield all next- siblings and descendants. types (None | int | tuple[int]), optional): The optional type filter. If None, all nodes will bey yielded. If not None, only nodes that inherit from at least one of the type symbols defined in the filter tuple will be yielded. Defaults to None. Yields: c4d.GeListNode: A node in the iteration sequence. Raises: TypeError: On argument type oopses. """ # Some argument massaging and validation. if not isinstance(node, c4d.GeListNode): msg = "Expected a GeListNode or derived class, got: {0}" raise TypeError(msg.format(node.__class__.__name__)) if isinstance(types, int): types = (types, ) if not isinstance(types, (tuple, list, type(None))): msg = "Expected a tuple, list or None, got: {0}" raise TypeError(msg.format(types.__class__.__name__)) def iterate(node, types=None): """The iteration function, walking a graph depth first. Args: same as outer function. Yields: same as outer function. """ # This or specifically the usage of the lookup later is not ideal # performance-wise. But without making this super-complicated, this # is the best solution I see here (as we otherwise would end up with # three versions of what the code does below). visisted = [] terminal = node.GetUp() if isinstance(node, c4d.GeListNode) else None while node: if node not in visisted: if types is None or any([node.IsInstanceOf(t) for t in types]): yield node visisted.append(node) if node.GetDown() and node.GetDown() not in visisted: node = node.GetDown() elif node.GetNext(): node = node.GetNext() else: node = node.GetUp() if node == terminal: break # For each next-sibling or descendant of the node passed to this call: for iterant in iterate(node): # Yield it if it does match our type filter. if types is None or any([iterant.IsInstanceOf(t) for t in types]): yield iterant # And iterate its tags if it is BaseObject. if isinstance(iterant, c4d.BaseObject): for tag in iterate(iterant.GetFirstTag(), types): yield tag def main(): """Entry point. """ # We iterate over all Xpresso tags in the document. We pass in the first # object in the scene and specify that we are only interested in nodes of # type c4d.Texpresso (Xpresso tags). for xpressoTag in NodeIterator(doc.GetFirstObject(), c4d.Texpresso): # Print out some stuff about the currently yielded Xpresso tag. name, nid = xpressoTag.GetName(), id(xpressoTag) print(f"The Xpresso tag {name} at {nid} has the nodes:") # Get its master node and root node in the Xpresso graph. masterNode = xpressoTag.GetNodeMaster() root = masterNode.GetRoot() # And iterate over all nodes in that root node. for xpressoNode in NodeIterator(root): print(f"\t{xpressoNode}") if __name__ == '__main__': main()1 point