Connect Multiply Object with saving Position/Rotation/Scale
-
Hello everyone, I ran into the simplest case that I introduced made me freeze for the whole evening.
Let's say there is a cube object, it has its own PRS (as in the screenshot). We apply GroupObjects to it, a parent object is created with the same coordinates as the cube itself.
Now, we're making Connect Objects so that it all becomes a normal editable object again. But for Axis, the position remains unchanged, and the rotation is reset. How to make sure that the PRS of the new object remains exactly the same as the original cube?
Of course, the simplest solution is to just copy the coordinates, but I'm looking forward to porting a huge game project with tens of thousands of such objects, each of which will have to repeat this over and over again (don't ask why, it's too long to explain). In general, doing it by hand is not an option.
I found out that the result I need can be achieved if I make a copy of the object, reset all its coordinates, do Connect + Delete, and then return it to its original place using the transfer. It remains only to automate this process.
So I decided to try to write a script that would do this.
I tried different methods, at the moment I settled on the fact that I instantiate the object (it remains in the right coordinates), the coordinates of the original object are reset and the connection + deletion occurs. And then, in theory, the coordinates of the PRS should be transferred from the instance to the original, followed by the removal of the instance, but this does not happen. There is a feeling that after combining the group into an object, the script loses the desired object and does not understand what to do next.
I apologize for the extremely incomprehensible story, I will be grateful for the answers and answer any questions.
Program code in its current form:
![from typing import Optional import c4d from c4d import gui doc: c4d.documents.BaseDocument op: Optional[c4d.BaseObject] def main(): objs = doc.GetActiveObjects(1) doc.StartUndo() for obj in objs: inst = c4d.BaseObject(c4d.Oinstance) inst.SetName(obj.GetName()+' Instance') inst[c4d.INSTANCEOBJECT_LINK]= obj doc.InsertObject(inst) inst()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] inst()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] = obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] inst()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] inst()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] inst()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] inst()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] = obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] inst()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_X] = obj()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_X] inst()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_Y] = obj()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_Y] inst()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_Z] = obj()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_Z] obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = 0 obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] = 0 obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = 0 obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = 0 obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = 0 obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] = 0 obj()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_X] = 1 obj()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_Y] = 1 obj()[c4d.ID_BASEOBJECT_REL_SCALE,c4d.VECTOR_Z] = 1 obj[c4d.CallCommand(16768)] obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = inst()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] = inst()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] obj()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = inst()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = inst()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = inst()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] obj()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] = inst()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] doc.EndUndo() c4d.EventAdd() if __name__ == '__main__': main()
-
Hi @DjNikMax , your images are not loading here ....
anyway this thread might help you
help-with-matrix-manipulation-after-c4d-mcommand_joincheers mogh
-
Hello @DjNikMax,
Welcome to the Plugin Café forum and the Cinema 4D development 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 Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are:
- Support Procedures: Scope of Support: Lines out the things we will do and what we will not do.
- Support Procedures: Confidential Data: Most questions should be accompanied by code but code cannot always be shared publicly. This section explains how to share code confidentially with Maxon.
- Forum Structure and Features: Lines out how the forum works.
- Structure of a Question: Lines out how to ask a good technical question. It is not mandatory to follow this exactly, but you follow the idea of keeping things short and mentioning your primary question in a clear manner.
About your First Question
The goal you're trying to achieve is a unclear and the proposed steps look redundant.
There're a couple of topics I'd like to mention regarding your provided code:
- Using
doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
doesn't make any sense in this context, because children are removed when calling "Connect Objects + Delete" command - Using
c4d.CallCommand(16768)
applies this command to the currently selected objects (rather than to the obj on the current loop iteration) - If you process objects one-by-one there's no need to group it beforehand, the "Connect Objects + Delete" command can be run directly on the object itself. This would bake rotation and scale into the mesh itself, the position would remain exactly the same as in the original object (without any extra step, no need to instantiate the object and copy it's coordinates back to the baked mesh)
- If you want to zero-out object position after baking it, you might want to look into freeze transform functionality: c4d.ID_BASEOBJECT_FREEZE_P
- If you anyways want to deal with transformations, you can check the thread about matrices, mentioned in above. @mogh, thank you for sharing!
Let me know if you still have any questions.
Cheers,
Ilia