Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Handles issue [SOLVED]

    SDK Help
    0
    3
    310
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post