Querying and Storing Object Information



  • Hello.

    I'm really new to using Cinema and Python together.

    In the object manager, you can get an object's information, such as how many points, polygons and memory it uses.
    I see there is a CallCommand to bring up the specific window with this information but I'd like it to be stored for later use.
    Looking though the documentation I see it is possible to query an object's points and polygons but I can't find how to do this for an object's memory.

    Would anyone know what that might be or what buzzwords would help me find that? I've tried "allocation", "memory", "object information" and things of the like. Thank you for any help!



  • hi,

    welcome to the forum :)
    Please, read our forum guidlines to know how to use the forum functionalities (ask question, tags)
    I've added the python tag and mark this thread as a question.

    Thanks @PluginStudent for pointing out that thread :)

    I would add that this depend on what exactly you are looking for. If it's just a matter of having the number of points and polygons, you have the function :
    GetPointCount
    GetPolygonCount

    You know that the point's position are stored in vector that are a structure that contain 3 floats. So you need to do :
    pointCount * 3 * size(float).
    size of a flot should be 64bits.

    You also need to do the same for polygons. (see CPolygon structure)

    You can also search in our GitHub repository for those function to find some examples.

    Cheers,
    Manuel



  • I don't think there is a function that returns the memory value, but some formula was discussed here: https://plugincafe.maxon.net/topic/12414/how-to-report-plugin-object-s-memory-usage-in-object-information/2



  • Oh ok interesing. Thanks for the link! That explanation they gave is shotty but I can try figuring it out. At least I know there isn't a direct method to call on.

    Thanks again.



  • hi,

    welcome to the forum :)
    Please, read our forum guidlines to know how to use the forum functionalities (ask question, tags)
    I've added the python tag and mark this thread as a question.

    Thanks @PluginStudent for pointing out that thread :)

    I would add that this depend on what exactly you are looking for. If it's just a matter of having the number of points and polygons, you have the function :
    GetPointCount
    GetPolygonCount

    You know that the point's position are stored in vector that are a structure that contain 3 floats. So you need to do :
    pointCount * 3 * size(float).
    size of a flot should be 64bits.

    You also need to do the same for polygons. (see CPolygon structure)

    You can also search in our GitHub repository for those function to find some examples.

    Cheers,
    Manuel



  • @m_magalhaes
    Apologies if I posted a bit haphazardly. Thanks for reorganizing where the post should be!

    I'm at day 3 of using Python in Cinema so I just need to get used to it all. I'll look into GetPointCount and GetPolygonCount.

    Essentially my friend wanted a tool that would organize what objects took the most memory and organized them from biggest to smallest in a log. I looked into VariableTag.GetDataCount and VariableTag.GetDataSize from what you described in the other post and those seem to be useful as well (I think).

    Thanks again!



  • Hi @Sturdy_Penguin,

    welcome to forum and I hope you had a interesting learning journey so far. But I would like to point out that "organiz[ing] what [...] took the most memory" is a not a trivial task in Cinema's Python, not to say an impossible one.

    1. In C++ you have the function sizeof, which you can use to measure the total size of an object and all its fields. The problem is when you have some form of linked data that this will obviously not be counted correctly. Which is why there is a special function in Cinema's internal API to measure the size of a BaseObject and roughly everything that is attached to it - its matching dialog will tell you that that number is an approximation.
      6d3229e7-95e9-4e50-b224-560053980e12-image.png

    2. This function has not been exposed to the public C++ or Python API.

    3. You can measure the size of objects (in the Pythonic sense) in Python itself with sys.getsizeof, but you will measure here the size of the python object that is the binding to the C++ data structure magened by Cinema 4D. The Python API is basically just one giant remote control. sys.getsizeof is in general a bit dicey, but for Cinema it is especially useless, e.g.:

    import c4d
    import sys
    
    
    def main():
        """
        """
        vec = c4d.Vector(1, 2, 3)
        print (sys.getsizeof(vec))
        # 40 <-- not the size of the vector, but of its Python wrapper.
        node = c4d.PolygonObject(4, 4)
        node.SetAllPoints([vec] * 4)
        print ("{:,}".format(sys.getsizeof(node)))
        # 69,342,398,996,512 <-- c4dpy thinks this object node takes up 69 TB,
        #                        which is rather unlikely ;)
    
    if __name__ == '__main__':
        main()
    
    1. So the only way is to do it manually, like @m_magalhaes has shown it in his posting, by multiplying the vertices and polygons by what you know they will take up in space (e.g., 24 bytes for a 64bit three component vector). The problem is that this will only work for editable polygon/spline objects in this manner, not for procedural objects - which make up the bulk of data in Cinema 4D. You need also to take tracks (animations) and tags into account which can make up the vast majority of the data that makes up an "object" (in the sense of Cinema).

    I do not want to to disencourage you, but I just wanted point out that this can be a bit steep hill to climb as a first project ;)

    Cheers,
    Ferdinand



  • @ferdinand Helloooo
    Thanks for all this great info! This is definitely much more convoluted than I anticipated. I appreciate the example you gave and your description of how I'd go about getting a close approximation. I do think it might be too difficult, especially because of Cinema's procedural objects.

    I was more so hoping that the "Object Information" menu was a callable function that I could simply ask to query the memory value for, then loop through every object and save to a log. I come from a background of Python for Maya so in my head I was thinking it'd be something like: object_size = maya.pymel.objectInfo ( object_name, query=True, size=True) but of course each software has it's own nature.

    My next thought (though probably entirely impossible) was to somehow execute "Object Information" for every object, somehow store the GUI dialog text as a string, close the dialog and save that information out.

    I'll probably look for a different starting point. Thanks again ♪(´▽`)



  • Hi,

    jeah, evaluating the dialog will probably be not a good solution. While you can technically raise the dialog with c4d.CallCommand(100004774) and evaluating its content and handle its closing could be done with some of the popular computer vision and automation libraries, the solution would be probably rather dodgy.

    But I would not say that the project has to be scrapped in its entirety, I would first go for evaluating to total number of vertices an object has, which should be a good indicator for its size. To do this properly you will have to also take the caches of an object into account. After that you would have to deal with tracks and tags in case you want a more complete solution. But I would go for the vertex counting problem first when trying to learn Cinema's API and make sure to get this working in all scenarios.

    Cheers,
    Ferdinand



  • Hi @Sturdy_Penguin ,

    without further questions or feedback, we will consider this thread as solved by Monday and flag it accordingly.

    Cheers,
    Ferdinand


Log in to reply