Volume Builder does not return object



  • I am using this code to convert a Volume Builder object into a mesh:

    def bake_drops():
    
        vm_drops = doc.SearchObject("VM Drops")
    
        vm_drops_return_value = c4d.modules.volume.SendVolumeCommand(
            command = c4d.VOLUMECOMMANDTYPE_VOLUMETOMESH,
            list = [vm_drops],
            bc = settings,
            doc = document)
    
        rig = vm_drops_return_value[0]
        
        doc.InsertObject(rig)
        rig.SetName ("Spritz " + drop_name)
    

    I get a True value when I print out vm_drops_return_value but I get and error message and no object when I try to run the code:

    Traceback (most recent call last):
    File "csto Python", line 184, in main
    File "csto Python", line 62, in bake_drops
    TypeError: 'bool' object has no attribute 'getitem'

    Can someone please tell me how to get the object? Thanks.



  • Looks like SendVolumeCommand fails, thus returning "false".
    Then in the line rig = vm_drops_return_value[0] you are basically trying to get an element from a bool, which of course doesn't work.

    You'll have to check against "false" first, then get the result. The documentation implicitly states that.

    You can find an example here. That command works the same way.



  • I get a True response.



  • @mp5gosu said in Volume Builder does not return object:

    here
    When I print
    print vm_drops_return_value
    I get a True value.
    When I print
    print vm_drops_return_value[0]
    I get
    Traceback (most recent call last):
    File "csto Python", line 153, in main
    File "csto Python", line 52, in bake_drops
    TypeError: 'bool' object has no attribute 'getitem'



  • @mp5gosu In the documentation here, it states that if the result is true, an object will be returned instead of a bool.

    Returns:
    True if the volume command succeeded, otherwise False.
    If the volume command succeeds the resulting objects are returned, if any, instead of True.


  • Global Moderator

    Hi Swinn,

    First of all, about the delay please read this announcement where we inform the community we would not be reachable while this 26th to 28th on September.
    Then when you post code, please use the correct markdown for code which is 3 single quote `` `.
    I also encourage you to read How to post questions in order to learn how to make use of the tagging system. And finally Q&A functionnaly To get used to of our new Q&A tools.

    With that's said, actually I agree, the function should not return True but False instead. I will report the issue.
    But in all case, the issue happens because you didn't fill the correct type of object (it should be a list of c4d.Ovolume object).
    You can get the settings of the command in the C++ documentation about VolumeToMeshSettings
    And here it's an example which makes use of VOLUMECOMMANDTYPE_VOLUMETOMESH

    import c4d
    
    # Main function
    def main():
        #Get the selected object
        volume = op
        if not volume: return
    
        # If it's a volume builder we access the volume Object
        if volume.CheckType(c4d.Ovolumebuilder):
            volume = volume.GetCache()
    
        # Check if we get a volume object
        if not volume.CheckType(c4d.Ovolume): return
    
        # Define our parameters for the volume commad
        objList = [volume]
        settings = c4d.BaseContainer()
        settings[c4d.VOLUMETOMESHSETTINGS_ISO] = 2.0
        settings[c4d.VOLUMETOMESHSETTINGS_ADAPTIVE] = 0.5
        document = doc
        
        # Call the Volume Command
        obj = c4d.modules.volume.SendVolumeCommand(
        command = c4d.VOLUMECOMMANDTYPE_VOLUMETOMESH,
        list = objList,
        bc = settings,
        doc = document)
        
        # If we get a boolean something went wrong
        if isinstance(obj, bool) and not obj[0].CheckType(c4d.Opolygon):
            return False
    
        # Insert the object in the scene
        doc.InsertObject(obj[0])
        c4d.EventAdd()
    
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    If you have any question, please let me know.
    Cheers,
    Maxime.



  • @m_adam Thank-you for your answer and code, Maxime. It works very well! I have one other question: I cannot seem to figure out how to factor in the Volume Mesher. Would I have to do a current state to object?

    0_1538403355867_CINEMA 4DScreenSnapz005.jpg

    PS I have followed your advice and read How to Post Questions and Q&A Functionality. As well, I will henceforth use the triple single quote notation for any code I post. Thank-you for your patience.


  • Global Moderator

    Hi @swinn can you elaborate a bit more when you said "To factor in" what would you like to do? Or what should be the final state of your "factoring".

    Thanks in advance.
    Cheers,
    Maxime



  • @m_adam Hi Maxime, here are 2 screen caps:

    1. This is what I would like to finish with. The Volume Builder sits under the Volume Mesher and creates this nice, smooth droplet object.

    2. This is the object produced by your code.

    Is there a way to create your object but with the Volume Mesher used as well? Thanks.

    0_1538495535389_CINEMA 4DScreenSnapz006.jpg

    0_1538495553097_CINEMA 4DScreenSnapz007.jpg


  • Global Moderator

    Hi @Swinn are you sure in your script you define in line 19/20

    settings[c4d.VOLUMETOMESHSETTINGS_ISO] = -5.51
    settings[c4d.VOLUMETOMESHSETTINGS_ADAPTIVE] = 0.0
    

    With the same value, you got in your volume mesher object? The voxel range threshold can't be directly passed as an argument, but you can expand this parameter in the volume mesher and then you get the Use Absolute Value (ISO) check box, which let you choose an ISO value.

    Cheers,
    Maxime.