Get visible objects from viewport in commandline



  • I think problem is C4d is not initialized BaseDraw from Commandline because BaseDraw, PickObject, GetFrame didn't in Gui console. I tried to take BaseDraw.GetSafeFrame () and got 0,0,0,0. Also tried to run the script from Gui, I was able to get GetFrame () when I did BaseDraw.InitializeView (self, doc, cam, editorsv) (but still not the same as the console in Gui). In fact PickObject, GetFrame work well in Gui console.



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



  • hi,

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

    Cheers,
    Manuel



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



  • 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
    


  • 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



  • @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



  • 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



  • 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



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



  • 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


Log in to reply