How to scale all objects in a scene at once?
-
I need to reactivate this thread. Everything that is posted here and in other posts doesn't really solve my problem.
I just want to have the same functionality as the scale project button but automated.
We have fbx imports that are too small (we can not change the scale in the export settings as there are no settings).
With all the stuff from this thread here the only thing that happens is, that we can change the project scale but not the actual scale of the 3D data which the Scale project button does.I mean if I want to have everything 10 times bigger I can change the project scale to 10 centimeters. So when copying it to a new scene or loading it as XRef with a project scale of 1 centimeter it seems to work but we already had problems with this workflow in the past with some shader scales or something that did not work properly.
So we changed to just use the "Scale project" button and type 10 in the target scale and this does the job.
I wanted to recreate this exact behaviour but the only way I see at the moment to just recreate this whole function by myself as there seems no way to scale your project. You can change the project scale or use a callcommand for the button but that just opens the window and I have to manually type in 10 and hit enter.What can I do to solve this problem? It seems so simple but I can not find a solution for that.
-
Hello @j_vogel,
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
As lined out above, please follow our support procedures. Thread necromancy usually leads to problems, at least when that much time has passed, I have forked this thread. Please also follow our rules about Support Procedures: Asking Questions, in short, we do not answer "please implement this or that for me".
The parameter
DOCUMENT_DOCUNIT
in a document is just something that is added to things like the coordinate manager, to set the unit and a multiplier for the numbers shown there. It will not scale the actual geometries (as it otherwise would be destructive) and therefore does not affect the view port.To scale all elements in the scene, you must scale all elements . You can use the command which we implemented for that, what is talked about above and which can be invoked with the button in the document scale settings. But you then have to use its UI, which is I guess not what you want. So, you would have write something like that yourself. But there is currently no premade scene traversal in Python which can be a bit daunting for beginners (will change with the next major release). Carrying out the scaling itself is not that hard, although this complexity can also vary based on the content. Since I know you have beta access: You can also pick the latest beta build, the traversal stuff is already in there.
Cheers,
FerdinandCode
"""Demonstrates how to scale all objects in a scene by a given factor. """ import c4d SCALE_FACTOR: c4d.Vector = c4d.Vector(2) # Scale factor for the objects, we pick a uniform scale of 2. doc: c4d.documents.BaseDocument # The currently active document. def IterateTree(node: c4d.GeListNode, yieldSiblings: bool = False) -> c4d.GeListNode: """Iterates over all descendants of the given #node and optionally its next siblings. In the next major release, there will be (finally) built-in scene traversal functions in Python. The one to pick for this case would be `mxutils.IterateTree`. Its signature is compatible with what I did here. """ def iterate(node: c4d.GeListNode) -> c4d.GeListNode: if not node: return yield node for child in node.GetChildren(): yield from iterate(child) while node: yield from iterate(node) node = node.GetNext() if yieldSiblings else None def main() -> None: """Called by Cinema 4D when the script is being executed. """ # Iterate over all objects in the document and scale them. for node in IterateTree(doc.GetFirstObject(), yieldSiblings=True): node.SetMl(node.GetMl() * c4d.utils.MatrixScale(SCALE_FACTOR)) c4d.EventAdd() if __name__ == '__main__': main()
edit: you should of course use the local and not global matrix, as you otherwise will scale things multiple times.