Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How to scale all objects in a scene at once?

    Cinema 4D SDK
    2
    2
    539
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic was forked from How to set project scale ferdinand
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      j_vogel
      last edited by

      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.

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @j_vogel
        last edited by ferdinand

        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,
        Ferdinand

        Code

        """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.

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • First post
          Last post