Handles issue [SOLVED]



  • On 30/10/2014 at 03:52, xxxxxxxx wrote:

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

    ---------
    Hi there, 
    i am having a hard time getting some handles to work. Most do what i think they should, but the last two (front/rear) don't. these get a weird offset as soon as i start dragging them.

    here is my code:

    #define pluginID 1000001
    #define pluginName "test"
      
    #include "c4d.h"
    #include "c4d_symbols.h"
    #include "c4d_gui.h"
    #include "test.h"
      
    class test : public ObjectData
    {
    	INSTANCEOF(test,ObjectData);
    private:
    	Real width,length,height,midOffset,front,rear;
    public:
    	virtual BaseObject* GetVirtualObjects(BaseObject *op, HierarchyHelp *hh);
    	virtual Bool Message(GeListNode *node, LONG type, void *t_data);
    	static NodeData *Alloc(void) { return gNew test; }
    	virtual Bool Init(GeListNode *node);
    	virtual Bool GetDParameter(GeListNode *node, const DescID &id, GeData &t_data, DESCFLAGS_GET &flags)  ;
    	virtual Bool GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags);
    	virtual Bool readParameters(BaseObject* op);
      
    	virtual LONG GetHandleCount(BaseObject *op);
    	virtual void GetHandle(BaseObject *op, LONG id, HandleInfo &info);
    	virtual void SetHandle(BaseObject *op, LONG i, Vector p, const HandleInfo &info);
    	virtual DRAWRESULT Draw(BaseObject *op, DRAWPASS type, BaseDraw *bd, BaseDrawHelp *bh);
    };
      
    Bool test::Init(GeListNode *node)
    {
    	BaseObject *op = (BaseObject* )node;
    	if (!op) return false;
    	BaseContainer *data = op->GetDataInstance();
    	if (!data) return false;
      
    	data->SetReal(WIDTH,100.0);
    	data->SetReal(HEIGHT,100.0);
    	data->SetReal(LENGTH,100.0);
    	data->SetReal(MIDOFFSET,0.0);
    	data->SetReal(FRONT,25.0);
    	data->SetReal(REAR,25.0);
      
    	return true;
    }
      
    Bool test::GetDParameter(GeListNode *node, const DescID &id, GeData &t_data, DESCFLAGS_GET &flags)  
    {
    	return SUPER::GetDParameter(node, id, t_data, flags);
    }
      
    Bool test::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags)
    {
    	if (!description->LoadDescription(node->GetType())) return false;
      
    	readParameters((BaseObject* )node);
      
    	flags |= DESCFLAGS_DESC_LOADED;
    	return SUPER::GetDDescription(node, description, flags);
    }
      
    Bool test::Message(GeListNode *node, LONG type, void *t_data)
    {
    	BaseObject *op = (BaseObject* )node;
    	if (!op) return false;
    	BaseContainer *data = op->GetDataInstance();
    	if (!data) return false;
        return true;
    }
      
    Bool test::readParameters(BaseObject* op) 
    {
    	if (!op) return false;
    	BaseContainer* bc = op->GetDataInstance();
    	if (!bc) return false;
    	width = bc->GetReal(WIDTH);
    	length = bc->GetReal(LENGTH);
    	height = bc->GetReal(HEIGHT);
    	midOffset = bc->GetReal(MIDOFFSET);
    	front = bc->GetReal(FRONT);
    	rear = bc->GetReal(REAR);
    	return true;
    }
      
    BaseObject *test::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)
    {
    	Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA);
    	dirty = dirty || !op->CompareDependenceList();
    	if (!dirty) 
    	{
    		return op->GetCache(hh);
    	}
    	BaseObject *main = BaseObject::Alloc(Onull);
    	main->SetName("test");
    	if (main)
    	{		
    		main->SetAbsPos(Vector(width*0.5,0,length*0.5));
    		return main;
    	}
    	return NULL;
    }
      
    Bool Register_test(void)
    {
    	GePrint(pluginName);
    	return RegisterObjectPlugin(pluginID,pluginName,OBJECT_GENERATOR|OBJECT_INPUT,test::Alloc,"Test",AutoBitmap("test.tif"),0);
    }
      
    /* Handles */
      
    LONG test::GetHandleCount(BaseObject *op)
    {
    	return 6;
    }
      
    void test::GetHandle(BaseObject *op, LONG id, HandleInfo &info)
    {
    	switch (id)
    	{
    		case 0: 
    			info.position = Vector(width, 0.0, 0.0); 
    			info.direction = Vector(1.0, 0.0, 0.0); 
    			break;
    		case 1: 
    			info.position = Vector(0.0, 0.0, length); 
    			info.direction = Vector(0.0, 0.0, 1.0); 
    			break;
    		case 2: 
    			info.position = Vector(width*0.5+midOffset, height, length*0.5); 
    			info.direction = Vector(0.0, 1.0, 0.0); 
    			break;
    		case 3: 
    			info.position = Vector(width*0.5+midOffset, 0.0, 0.0); 
    			info.direction = Vector(1.0, 0.0, 0.0); 
    			break;
    		case 4: 
    			info.position = Vector(width*0.5+midOffset, height, front); 
    			info.direction = Vector(0.0, 0.0, 1.0); 
    			break;
    		case 5: 
    			info.position = Vector(width*0.5+midOffset, height, length-rear); 
    			info.direction = Vector(0.0, 0.0, 1.0); 
    			break;
    	}
      
    	info.type = HANDLECONSTRAINTTYPE_LINEAR;
    }
      
    void test::SetHandle(BaseObject *op, LONG i, Vector p, const HandleInfo &info)
    {
    	BaseContainer *bc = op->GetDataInstance();
    	if (!bc) return;
      
    	HandleInfo inf;
    	GetHandle(op, i, inf);
    	float val = (p - inf.position) * inf.direction;
      
    	switch (i)
    	{
    		case 0: bc->SetReal(WIDTH, bc->GetReal(WIDTH)+val); break;
    		case 1: bc->SetReal(LENGTH, bc->GetReal(LENGTH)+val); break;
    		case 2: bc->SetReal(HEIGHT, bc->GetReal(HEIGHT)+val); break;
    		case 3: bc->SetReal(MIDOFFSET, bc->GetReal(MIDOFFSET)+val); break;
    		case 4: bc->SetReal(FRONT, bc->GetReal(FRONT)+val); break;
    		case 5: bc->SetReal(REAR, bc->GetReal(REAR)-val); break;
    	}
    }
      
    DRAWRESULT test::Draw(BaseObject *op, DRAWPASS type, BaseDraw *bd, BaseDrawHelp *bh)
    {
    	if (type==DRAWPASS_HANDLES) 
    	{
    		LONG i;
    		HandleInfo info;
    		
    		Matrix m=bh->GetMg();
    		bd->SetMatrix_Matrix(op, m);
    		bd->SetPen(Vector(1.0,1.0,1.0));
    		bd->SetPointSize(5.0);
      
    		for (i = GetHandleCount(op) - 1; i >= 0; --i)
    		{
    			GetHandle(op, i, info);
    			bd->DrawHandle(info.position, DRAWHANDLE_CUSTOM, 0);
    		}
    		bd->DrawLine(Vector(0.0,0.0,0.0),Vector(0.0,0.0,length),NOCLIP_D);
    		bd->DrawLine(Vector(width*0.5+midOffset,0.0,0.0),Vector(width*0.5+midOffset,0.0,length),NOCLIP_D);
    		bd->DrawLine(Vector(width,0.0,0.0),Vector(width,0.0,length),NOCLIP_D);
    		bd->DrawLine(Vector(0.0,0.0,length),Vector(width,0.0,length),NOCLIP_D);
    		bd->DrawLine(Vector(0.0,0.0,0.0),Vector(width,0.0,0.0),NOCLIP_D);
    		bd->DrawLine(Vector(width*0.5+midOffset,0.0,length*0.5),Vector(width*0.5+midOffset,height,length*0.5),NOCLIP_D);	
    		bd->DrawLine(Vector(width*0.5+midOffset,height,front),Vector(width*0.5+midOffset,height,length-rear),NOCLIP_D);
    	}
      
    	return SUPER::Draw(op, type, bd, bh);
    }
    

    hopefully someone can jump in and show my what i am doing wrong.

    cheers,
    ello



  • On 30/10/2014 at 10:09, xxxxxxxx wrote:

    Hello,

    Why are you drawing the handles in the Draw() function? Cinema should draw the handles for you in the viewport.

    Please keep in mind that GetHandle() is not just called to initiate the handles but also to set their position. I'm not quite sure about what you are doing in SetHandle(), can you elaborate that a little bit?

    best wishes,
    Sebastian



  • On 30/10/2014 at 10:56, xxxxxxxx wrote:

    thanks for your input. i moved the readParameters into the GetHandle and it works now. seems that somehow the variables got refreshed at the wrong place. SetHandle passes the changes to the parameters. And i have the DrawHandle call because i want to apply colors to the handles lateron.

    i had a look at the roundedTube example from the sdk folder.. to have a starting point.


Log in to reply