Update in UD link does not update object in Volume Builder Object List
-
I am trying to automatically update the object list in a Volume Builder. I am using a User Data link. When I drop a new object in the UD link field, the object in the Volume Builder list does not update. Is there a way to do this? Below is the code I am using:
import c4d from c4d.modules import volume import pprint from c4d import documents from c4d import utils Bake_Button = 240 obj = op.GetObject() #obj = doc.SearchObject("Spritz 4.0") UD = obj.GetUserDataContainer() bottle = obj[c4d.ID_USERDATA,5] set_bottle = 242 delete_bottle = 243 document = op.GetDocument() settings = c4d.BaseContainer() selected = doc.GetActiveObjects(0) taglist = doc.GetActiveTags() presets = obj[c4d.ID_USERDATA,13] drop_name = obj[c4d.ID_USERDATA,197] def set_delete_UD_object(): vol_build = doc.SearchObject("VB Drops") vol_build_drip_1 = doc.SearchObject("VB Drip 1") if obj[c4d.ID_USERDATA, set_bottle] == 1: vol_build.AddSceneObject(bottle, index = 0) vol_build.SetBoolMode(0, 2) vol_build_drip_1.AddSceneObject(bottle, index = 0) vol_build_drip_1.SetBoolMode(0, 2) obj[c4d.ID_USERDATA, set_bottle] = False for descId, container in UD: # SET Object hide if descId[1].id == 266: container[c4d.DESC_HIDE] = True obj.SetUserDataContainer(descId, container) for descId, container in UD: # DELETE Object show if descId[1].id == 267: container[c4d.DESC_HIDE] = False obj.SetUserDataContainer(descId, container) if obj[c4d.ID_USERDATA, delete_bottle] == 1: vol_build.RemoveObject(0) vol_build_drip_1.RemoveObject(0) obj[c4d.ID_USERDATA, delete_bottle] = False for descId, container in UD: # SET Object show if descId[1].id == 267: container[c4d.DESC_HIDE] = True obj.SetUserDataContainer(descId, container) for descId, container in UD: # DELETE Object hide if descId[1].id == 266: container[c4d.DESC_HIDE] = False obj.SetUserDataContainer(descId, container) def main(): set_delete_UD_object()
-
Hi @Swinn no worries, but please make sure to use Q&A functionality .
According to your description, I made my own setup, with a Null which gets a userData link. Then I attach a python script to this Null object.
I also created a Volume Builder calledVolume Builder
. Using the following code it's working as expected.import c4d from c4d.modules import volume def main(): # Get the host object and the linked obj from the user data obj = op.GetObject() linkedObj = obj[c4d.ID_USERDATA,1] if not linkedObj: return # Get the volume builder vBuilder = doc.SearchObject("Volume Builder") if not vBuilder and not vBuilder.CheckType(c4d.Ovolumebuilder): return # Check if our object is not already in the list allowedObj = [linkedObj] # Maybe you got some other object you don't want to delete alreadyIn = False for i in xrange(0, vBuilder.GetListEntryCount()): o = vBuilder.GetInputObject(i) # If is not in our list of allowed objects we remove it if o not in allowedObj: vBuilder.RemoveObject(i) # If our linked object is already in the list if o == linkedObj: alreadyIn = True # Only add if the object is not already in the list if not alreadyIn: vBuilder.AddSceneObject(linkedObj) vBuilder.SetBoolMode(0, 2)
Maybe you can try to reduce your code. Moreover, it looks like you are adding and deleting the bottle at the same time.
Additionally, I would not recommend you to define variables in global space of the script but rather in local space of your function.
if you have any question, please me know!
Cheers,
Maxime. -
This is starting to work but it now adds 2 user data objects. As well, do I need to add an event to get a refresh? Also, I am trying to move the linked user data object to the top of the hierarchy but it doesn't want to go there. And finally, MIST Cloner and SMALL DROPS Cloner keep switching places.
import c4d from c4d.modules import volume def main(): # Get the host object and the linked obj from the user data obj = op.GetObject() linkedObj = obj[c4d.ID_USERDATA,5] if not linkedObj: return # Get the volume builder vBuilder = doc.SearchObject("VB Drops") if not vBuilder and not vBuilder.CheckType(c4d.Ovolumebuilder): return # Check if our object is not already in the list allowedObj = [linkedObj] # Maybe you got some other object you don't want to delete alreadyIn = False for i in xrange(0, vBuilder.GetListEntryCount()): o = vBuilder.GetInputObject(i) # If is not in our list of allowed objects we remove it if o not in allowedObj: vBuilder.RemoveObject(i) # If our linked object is already in the list if o == linkedObj: alreadyIn = True # Only add if the object is not already in the list if not alreadyIn: vBuilder.AddSceneObject(linkedObj, index = 0) vBuilder.SetBoolMode(0, 2)
I have added index = 0 to your code but it doesn't seem to work.
-
Hi @Swinn, if you add another object through another UserData link, then you have to properly insert it, and keep track of it inside the volume builder as well and handle the "refresh" yourself as I demonstrated in my previous example.
Since you are doing it for more than one object, in my previous example I used a variable called alreadyIn, to keep track of my object. But it was a very simple example.
If you are switching to multiple objects, it may be worth making a data structure where you hold the objects, and if these are already inserted or not, in order to be able to track your objects properly.In the end this is probably more an algorithmic problem, and not that much API related. Thus we as the SDK Team can only give advice and suggest a direction.
Moreover, in your code, I don't see any link to the new UserData link. And you are still deleting 'BIG DROPS CLONER' and all others custom cloners you have in your image. Are you sure you use the same code than the one you posted?
Furthermore
vBuilder.AddSceneObject(linkedObj, index = 0)
respects the order, with index parameter set to zero linkedObj will be correctly inserted at the top of the list.Cheers,
Maxime! -
@m_adam Cool. Thank-you for your time and patience.