Instant update when target object changes [SOLVED]



  • On 24/05/2016 at 12:44, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   17 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hello. In my ObjectData plugin that has a (large) number of parameters, i would like to add the the option to get the parameter values from a "target" of the same object type.

    the way i'm doing it is by having a link that only accepts target of same type and then extracting the BaseContainer data which is passed along to a polygon generator function. if there is no target then the function uses the object's own data

    It works as intended, except that when the target changed, it doesn't update in real-time (i need to enable and disable the object to see the changes). here's what i tried

    >

    BaseObject* SubdivObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)  
    \> {  
    \> 	BaseObject* orig = op->GetDown();  
      
    \> 	// return if no input object is available
    \> 	if (!orig)  
    \> 		return nullptr;  
    \>   
    \> 	Bool dirty = false;  
    \> 	Bool target_dirty = false;  
      
    \> 	// generate polygonalized clone of input object
    \> 	BaseObject* main = nullptr, *res = op->GetAndCheckHierarchyClone(hh, orig, HIERARCHYCLONEFLAGS_ASPOLY, &dirty, nullptr, false);  
      
    \> 	//get data from target object
    	BaseObject* target = (op->GetDataInstance())->GetObjectLink(SUBDIVOBJECT_OPTIONS_TARGET, hh->GetDocument());
    \>        //check if target is dirty
    \> 	if (target != nullptr) target_dirty = target->IsDirty(DIRTYFLAGS_DATA);  
      
    \> 	// if !dirty && !target_dirty object is already cached and doesn't need to be rebuilt
    \> 	if (!dirty && !target_dirty)  
    \> 	{  
    \> 		return res;  
    \> 	}  
    \> 	if (!res)  
    \> 		return nullptr;  
    \>   
    \> 	// get object container  
    \> 	BaseContainer* bc;  
    	BaseContainer* bc_ = op->GetDataInstance();
    \> 	//check if there is a target and pass its data to Recurse
    \> 
    \>        //if not use object own data
    	if (target == nullptr) bc = bc_; 
    \> 	else bc = target->GetDataInstance();  
    \>   
    \> 	BaseThread*		 bt = hh->GetThread();  
      
    \> 	// group all further objects with this null object
    \> 	main = BaseObject::Alloc(Onull);  
    \> 	if (!main)  
    \> 		goto error;  
      
    \> 	// go through all child hierarchies
    \> 	if (!Recurse(hh,bc, bt, main, res, orig->GetMl()))  
    \> 		goto error;  
    \> 	blDelete(res);  
    \>   
    \> 	return main;  
    \>   
    \> error:  
    \> 	blDelete(res);  
    \> 	blDelete(main);  
    \> 	return nullptr;  
    \> }
    

    > >
    >
    I thought a solution would be to check if the target is dirty, and if it was, to flush the cache and generate the polygon. that doesn't seem to work. To see any changes after changing the parameters of the target (i need to enable and disable the object. Same story if i use DIRTYFLAGS_ALL when calling IsDirty on the target. Any hints are appreciated.



  • On 25/05/2016 at 02:12, xxxxxxxx wrote:

    Hello,

    BaseObject::IsDirty() is part of the workflow that handles generator input child objects (with Touch() etc.). I think what you actually want is C4DAtom::GetDirty(). This function would return the current dirty checksum.

    So when you resolve the link you first would have to check if the given BaseObject is the same object as previously or a different object. If it is a different object you probably should update. Only when it is the identical object you would have to compare the dirty checksum of GetDirty() with a previously stored value.

    The only existing dependency system for generators is the use of child objects (with OBJECT_INPUT). Other configurations may or may not work completely.

    Best wishes,
    Sebastian



  • On 27/05/2016 at 11:14, xxxxxxxx wrote:

    Thanks Sebastian. That seems to work. cheers!


Log in to reply