Automating Dynamic Place
-
Hi,
I'm trying to write a script to place an object with an irregular shape onto a flat background object (like a floor). Is there a way to reproduce what the Dynamic Place (moving the Y-axis only) until it naturally sits on the floor? I'm writing a script that sets up several image renders at different angles at each frame.
The bounding box can't be used since the shape isn't regular and doesn't shrink wrap properly.
Anyone have a possible direction/solution?
Thanks!
-
Hello @markeee,
Welcome to the Maxon developers forum and its community, it is great to have you with us!
Getting Started
Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.
- Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
- Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
- Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.
It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: Asking Questions.
About your First Question
I really do not want to demotivate you in your first posting, but what you are trying is not trivial and this is one of the cases where when you have to ask, it is probably not for you. The Place tool is not exposed in the public API and so is not the general Rigid Body Dynamics API. Writing something like the place tool yourself is a very hard task.
What is relatively easy, is just to create an RBD setup, and then animate that for X frames, in the hopes that it until then has settled.
Cheers,
FerdinandResult
"""Creates a little RBD setup to place an object on top of another object. I am using here a plane as the object to settle on, but it could also be a non-planar object. Must be run as a Script Manager script and will place/create a Platonic, as if it had fallen on the world grid and settled on the origin of it. Since this must run a simulation, the script will run a while (and block the UI in the mean time). One could make this nicer with threading and statusbar spam, but I did not :) """ import c4d import mxutils doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: """Called by Cinema 4D when the script is being executed. """ # Generate a platonic object and a plane object, scale up the plane, move the platonic 500 units # up on the y-axis, and finally create a little RBD setup. platonic: c4d.BaseObject = mxutils.CheckType(c4d.BaseObject(c4d.Oplatonic)) plane: c4d.BaseObject = mxutils.CheckType(c4d.BaseObject(c4d.Oplane)) plane[c4d.PRIM_PLANE_WIDTH] = 5000 plane[c4d.PRIM_PLANE_HEIGHT] = 5000 platonic.SetMg(c4d.Matrix(off=c4d.Vector(0, 500, 0))) mxutils.CheckType(plane.MakeTag(c4d.Tcollider)) rbd: c4d.BaseTag = mxutils.CheckType(platonic.MakeTag(c4d.Trigidbody)) rbd[c4d.RIGIDBODY_PBD_CUSTOM_INITIAL_VELOCITY] = True rbd[c4d.RIGIDBODY_PBD_CUSTOM_INITIAL_ANGULAR_VELOCITY] = True rbd[c4d.RIGIDBODY_PBD_INITIAL_LINEAR_VELOCITY] = c4d.Vector(-.1) # Create a dummy document, insert our little rig, and execute the passes for 100 frames, in the # hopes that the platonic has settled until then. temp: c4d.documents.BaseDocument = mxutils.CheckType(c4d.documents.BaseDocument()) temp.InsertObject(plane) temp.InsertObject(platonic) fps: int = temp.GetFps() for i in range(100): temp.SetTime(c4d.BaseTime(i, fps)) if not temp.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE): raise RuntimeError(f"Failed to execute pass for {c4d.BaseTime(i, fps)} for {temp}.") # Get the matrix from the settled object. We can zero out the x/z pos, so that the objects sits # dead-center in the world grid. mg: c4d.Matrix = platonic.GetMg() mg.off = c4d.Vector(0, mg.off.y, 0) # Create a new platonic (with the same settings) and insert into the active document and set our # computed matrix. result: c4d.BaseObject = mxutils.CheckType(c4d.BaseObject(c4d.Oplatonic)) result.SetMg(mg) doc.InsertObject(result) # Cinema 4D will garbage collect #temp and its content on its own, but we can call flush to make # it a bit cleaner. temp.Flush() # Push an update event. c4d.EventAdd() if __name__ == '__main__': main()
-
Thanks Ferdinand, I totally understand I'm above my head. If I were to hire someone to do this, would it be possible you think? Or even there, it's so pigeon-holed that it's futile.
I will go and read the links you provided.
Markeee