How to do that the generated object fill the viewport and be centered



  • Hello,

    How to do that the genertaed object fill the viewport and be centered, because the object is too large.
    I tried to use the c4d.CallCommand(12148) inside the GetVirtualObjects() function but this doesn't work. its work only if I use it inside Message() function.

    is there a possibility to do that using python

    Thank you.



  • Hi,

    at least for me it is really hard to answer your question in the current form.

    Modifying the active camera (letting an object fill the view) is quite an unusual thing for both a Python Generator Object and a ObjectData plugin to do. You might want to reconsider your approach. Also worth mentioning is that ObjectData.GetVirtualObjects() is executed in a threaded context, in which it is forbidden or disencouraged to modify the scene or add events. Invoking the 'center in view'-command does both (it modifies the editor camera object), so unexpected behavior is in this case actually to be expected ;)

    To get better help you should post your code and describe your problems more in detail.

    Cheers
    zipit



  • @zipit
    Hi,
    I created the following example just to demonstrate my issue:
    Code:

    class MyCube(plugins.ObjectData):
        def Init(self, op):
            self.SetOptimizeCache(True)
    
            self.InitAttr(op, float, [c4d.MYCUBE_OBJECT_WIDTH])
            self.InitAttr(op, float, [c4d.MYCUBE_OBJECT_HEIGHT])
            self.InitAttr(op, float, [c4d.MYCUBE_OBJECT_DEPTH])
    
            data = op.GetDataInstance()
            
            data.SetFloat(c4d.MYCUBE_OBJECT_WIDTH, 1600.0)
            data.SetFloat(c4d.MYCUBE_OBJECT_HEIGHT, 1000.0)
            data.SetFloat(c4d.MYCUBE_OBJECT_DEPTH, 1500.0)
    
            return True
    
        def GetVirtualObjects(self, op, hierarchyhelp):
    
            width = op[c4d.MYCUBE_OBJECT_WIDTH]
            height = op[c4d.MYCUBE_OBJECT_HEIGHT]
            depth = op[c4d.MYCUBE_OBJECT_DEPTH]
    
            cube = c4d.BaseObject(c4d.Ocube)
    
            cube[c4d.PRIM_CUBE_LEN, c4d.VECTOR_X] = width
            cube[c4d.PRIM_CUBE_LEN, c4d.VECTOR_Y] = height
            cube[c4d.PRIM_CUBE_LEN, c4d.VECTOR_Z] = depth
            
            return cube
    

    And here is an screenshot for the given result :

    my-cube-python.jpg

    The object is too large and it cut off in the viewport, and my object must be with the given dimensions above



  • Hi,

    while what you are doing is much clearer now, I still do not really get your problem ;) An ObjectData plugin that implements GetVirtualObjects is not really supposed to modify the scene camera. Therefor I am a bit hesitant to tell you ways how you could circumvent the threaded context of GVO.

    Just consider an user has three of your MyCube objects in his/her scene and has animated a parameter in each of these objects. When he/she starts the scene playback GVO will be invoked for each object at least once per frame. If you had some sort of camera logic attached to the execution of your GVO, the scene camera would wildly jump from object to object for each frame and the user would not be able to interact with the scene anymore.

    If you really want to have some sort of "frame this object"-logic attached to your object, I would propose adding a button to your description resource and then frame the object when the user presses that button.

    Cheers
    zipit



  • @zipit
    My object is limited to only one Object instance by document, (is not possible to open more than one object in current document). It is a studio light kit that will contain a lot of objects. I had thought about adding button to do that.
    Anyway, thank you very much for your help. I will probably adding button to do that.



  • Hello,

    As Zipit said, this is not the right place to trigger event or change the scene.

    What I would like to know is if it's a "once shot" or "always".

    If it's one shot, you could Create a script or a commandData that will add your generator to the scene and take care of changing the camera to Frame it. This is allowed.

    If it's "always"
    As I understand, you are going to create a Cube (we know the size) and put object Inside it ?
    So you can move your cube backward (in camera space). You just have to check if your 8 points are in the frame.

    That remember a bit this post. You will find code and information to check if your object is framed..
    Once again, don't update the scene or move the camera in a generator.

    hope that helped.

    Cheers,
    Manuel



  • @m_magalhaes
    Hello,

    it's a "once shot" I would like to execute this command only on the first object open. in the case if the object is saved and reopened the command should not be re-executed. And also I don't want to move the object out of the world center.

    No problem, I will just add a button to my description resource and run the command c4d.CallCommand(12151) # Frame Selected Objects

    Thank you.



  • Hi,

    if you only want to frame the object on instantiation and also want to restrict the user to only being able to create one of your objects (which you cannot really do either in a safe way from within an ObjectData plugin), then the solution proposed by @m_magalhaes - writing a CommandData wrapper - is probably the best solution, as it can do both easily.

    Cheers
    zipit



  • hi,

    We already talked on this thread about how to limit the number of object in a scene.

    (it's cool to see tools coming to life)

    So if you just want to frame the object from time to time, and still want to have that in your interface, i think the button is probably the best solution.

    Cheers,
    Manuel



  • hello,

    without any news, i'll pass this thread to solved.

    Cheers,
    Manuel



  • @m_magalhaes
    Hello Manuel,
    ok Thank you. I have used the solution that I have mentioned above.


Log in to reply