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

    Get visible objects from viewport in commandline

    Cinema 4D SDK
    3
    11
    1.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      ac3 @ac3
      last edited by

      I am writing a script that runs the C4d command line ("Commandline.exe" - nogui, etc.) and works in it.The Gui console is the console that is called with shift+F10 in c4d.

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        hi,

        it's not really clear, what is your final goal ?

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        A 1 Reply Last reply Reply Quote 0
        • A
          ac3 @Manuel
          last edited by

          @m_magalhaes
          Hi, I want to get an array of visible objects from "camera view", via cinema 4d commandline.exe if possible 🙂

          1 Reply Last reply Reply Quote 0
          • A
            ac3
            last edited by

            Code example:

            import os
            import sys
            
            import c4d
            
            def PluginMessage(_id, data):
                if _id == c4d.C4DPL_COMMANDLINEARGS:
                	print sys.argv
                    walker()
                    return True
                return False
            
            def walker(step_x=5,step_y=5):
                    doc = c4d.documents.GetActiveDocument()
                    print "Document: {}".format(doc)
                    bd = doc.GetRenderBaseDraw()
                    print "BaseDraw: {}".format(bd)
                    safeframe = bd.GetSafeFrame()
                    print "SafeFrame: {}".format(safeframe)
            
                    arr_o = []
                    for y in range(safeframe['cl'],safeframe['cr'],step_y):
                        for x in range(safeframe['ct'],safeframe['cb'],step_x):
                            o = c4d.utils.ViewportSelect.PickObject(bd, doc, x, y, rad=1, flags=c4d.VIEWPORT_PICK_FLAGS_OGL_ONLY_TOPMOST_WITH_OBJ | c4d.VIEWPORT_PICK_FLAGS_OGL_ONLY_VISIBLE)
                            if o:
                                try:
                                    arr_o.append(o[0])
                                except IndexError as e:
                                    print(e)
                    print "Array of objects: {}".format(arr_o)
                    return arr_o
            

            Output:

            ['C:\\Users\\Administrator\\Documents\\1.c4d', '-nogui']
            Document: <c4d.documents.BaseDocument object called '' with ID 110059 at 0x00000
            08ABA5CC3B0>
            BaseDraw: <c4d.BaseDraw object called 'Perspective' with ID 110305 at 0x0000008A
            BA5CC3F0>
            SafeFrame: {'cr': 0, 'ct': 0, 'cb': 0, 'cl': 0}
            Array of objects: []
            

            Cmd command:

            C:\Program Files\MAXON\Cinema 4D R20>Commandline.exe "C:\Users\Administrator\Documents\1.c4d" -nogui
            
            1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand
              last edited by ferdinand

              Hi,

              the BaseDraw is probably not being properly initialised due to being hosted by a GUI-less environment. I also would be surprised, if ViewportSelect would work properly in this environment. You could either ray-intersection test all objects in the scene by firing rays (with GeRayCollider) through a grid on the view plane of the camera - similarly to what you are doing in your script. But that would be slow and prone to False Negatives (i.e. stepping over very small objects) like that grid approach is in general. The advantage of that approach is that it will produce no False Positives unlike the following approach.

              The much faster and more common way would be to intersection test the bounding box of each object with the view frustum of the camera. One common algorithm is the Axis-Aligned-Bounding-Box (AABB) algorithm which comes in many flavours. There is a nice educational paper on the topic of cone/box intersections by David Eberly, but if you google for AABB intersection, you will find many more.

              Cheers,
              zipit

              MAXON SDK Specialist
              developers.maxon.net

              A 1 Reply Last reply Reply Quote 0
              • A
                ac3 @ferdinand
                last edited by

                @zipit , Hi.
                The methods you suggested will not work for me, since bbox has an error(example: if the bbox of a sphere is included in one corner of the frame, but the sphere itself does not fall into our frame, the source masive will have a sphere object), and GeRayCollider because It does not return objects.

                Maybe you know how to initialize ViewportSelect to make It work, maybe there is the same method as loading caches for objects in Commandline.exe

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

                  Hi,

                  I am aware that AABB frustum culling will produce False Positives, that is why I mentioned it 😉 However, I am not quite sure, if you are aware that your method, either by manually ray-casting, like I proposed, or by using ViewPortSelect is subject to False Negatives, i.e. can report misses where it should report hits. That hapens when your ray-casting grid is to broad.

                  Also: The ray-casting method proposed be me is verly likely very close to what ViewPortSelect is doing internally. Note that GeRayCollider has a glancing hit functionality, which would let you compensate for the grid approach weakness, i.e. emulate the radius argument of ViewPortSelect.

                  Finally, while technically you can instantiate a BaseDraw from scratch, you cannot specify the screen dimensions of its super class BaseView, nor are you able to modify these attributes on an existing instance. So when Cinema gives you only a "dummy" BaseDraw with the zero vector for its dimensions, you are cannot use ViewPortSelect since it relies on a BaseDraw for its inputs.

                  Cheers,
                  zipit

                  MAXON SDK Specialist
                  developers.maxon.net

                  1 Reply Last reply Reply Quote 0
                  • ManuelM
                    Manuel
                    last edited by

                    hi,
                    the problem isn't coming from the fact that there's no GUI but that c4d didn't finished to initialized. Even with the UI, it's the same problem.
                    I'm trying to find a place where you could/catch the right message but until now, all the solution have failed.

                    But i still have one solution or two on my pocket.

                    Cheers,
                    Manuel

                    MAXON SDK Specialist

                    MAXON Registered Developer

                    A 1 Reply Last reply Reply Quote 0
                    • A
                      ac3 @Manuel
                      last edited by

                      Hi,@m_magalhaes
                      I tried all the messages, and did not find where this could work. Could you tell me the right solution?

                      1 Reply Last reply Reply Quote 0
                      • ManuelM
                        Manuel
                        last edited by Manuel

                        hi,

                        I tried creating a CommandData that you could be triggered with a parameter --> not working
                        I tried creating a ObjectData that could react to MSG_DOCUMENTINFO in its Message function when the document is loaded --> not working
                        I tried when the program is closing --> not working

                        Based on my knowledge, there's no solution for your issue.

                        Cheers,
                        Manuel

                        MAXON SDK Specialist

                        MAXON Registered Developer

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