IN_EXCLUDE and multiple drops



  • On 27/02/2016 at 15:40, xxxxxxxx wrote:

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

    ---------
    There is an interesting problem with an IN_EXCLUDE list in my plugin object.  It only accepts Polygon Objects (Opolygon).  If there is a second Attribute Manager opened and locked to my plugin object, the user could 'hypothetically' (and by this, I mean, can) drop multiple objects from the Object Manager into the IN_EXCLUDE list.  The result is that all of the objects are accepted, no matter the type, if any of them is acceptable.   And, yes, I have also tried using MSG_DESCRIPTION_CHECKDRAGANDDROP to restrict the acceptance but it doesn't seem to work either.

    Is there a particular message sent after the objects have been accepted and dropped into the list?



  • On 27/02/2016 at 16:03, xxxxxxxx wrote:

    This appears to work (called from Message()) :

    // V4DObject.MsgCheckUpdate
    //*---------------------------------------------------------------------------*
    Bool V4DObject::MsgCheckUpdate(DescriptionCheckUpdate* dcu, BaseObject* op)
    //*---------------------------------------------------------------------------*
    {
    	if (!dcu)
    		return TRUE;
    	//GePrint("MsgCheckUpdate");
    	BaseContainer*			bc =	op->GetDataInstance();
    	if (!bc)
    		return TRUE;
    	Int32					id =	(*(dcu->descid))[0].id;
    	if (id == V4DOBJECT_HOST_OBJECTS)
    	{
    		InExcludeData* pObjList = (InExcludeData* )bc->GetCustomDataType(V4DOBJECT_HOST_OBJECTS,CUSTOMDATATYPE_INEXCLUDE_LIST);
    		if (pObjList)
    		{
    			BaseDocument*	pDoc =	op->GetDocument();
    			BaseObject*	obj = NULL;
    			for (Int32 i = 0; i < pObjList->GetObjectCount(); ++i)
    			{
    				obj = (BaseObject* )pObjList->ObjectFromIndex(pDoc, i);
    				if (obj)
    				{
    					if (!obj->IsInstanceOf(Opolygon))
    						pObjList->DeleteObject(i);
    				}
    				else
    					pObjList->DeleteObject(i);
    			}
    			op->SetDirty(DIRTYFLAGS_DATA);
    		}
    	}
    	return TRUE;
    }
    


  • On 28/02/2016 at 01:31, xxxxxxxx wrote:

    Hi Robert,

    I confirm this behavior you describe.

    Imo this behavior is a bug (ok, maybe "bug" is a too strong word. Most probably the dev who implemented this for R16 simply didn't think about this situation. So let's say it doesn't behave as it should or as one would expect).

    Message is called several times for an InExclude drop (instead of just once having drop->element to be an array of objects for example).
    If Message is called several times for each dropped element, then the drop check result (filling of dropdata->result) should be considered for each element.

    But it doesn't: As soon as dropdata->result is true once, the check stops and all dragged objects are accepted. Even if you drop 100 objects and only the last object fills dropdata->result = true, then all 100 are accepted. Doesn't seem right.

    So either you go the route you have already taken, or hold a class variable and keep dropdata->result = false, whenever you encounter at least one incompatible drop element.



  • On 29/02/2016 at 04:05, xxxxxxxx wrote:

    Hi Robert,

    I also confirm the behavior. As a workaround you can alternatively loop through the active objects as these are the dragged and dropped objects.

    I will report this issue as Cinema should not accept the drop of several objects when at least one is not of an acceptable type. In that case it should not also send MSG_DESCRIPTION_CHECKDRAGANDDROP message as it already knows drop is not valid.

    And I agree MSG_DESCRIPTION_CHECKDRAGANDDROP should give an array of dragged elements, not only one element. One element is enough for a Link but not for an InExclude.


Log in to reply