Handles Problem...

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 14/09/2003 at 16:51, xxxxxxxx wrote:

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

---------
I have some handles for my object plugin but I ran into a problem. When using the handles to control a Real field with Meter or no "units" then it works perfectly but when using it for a field that has percentage units its range is too wide. Means when moving the handle 100 units then I want the percentage field to be at 100% but it´s at 10000%.
ok, so this seems to be a simple task, just divide the resulting value with 100 and it should work. But it´s not. Then the handle is placed wrong again :
So, can somebody help me out here. Where or how to get the correct behavior (or where to divide...)
Heres a code snippet (using a vector field, x component) :
Bool DPDub::MoveHandle(PluginObject *op, PluginObject *undo, const Matrix &tm, LONG hit_id, LONG qualifier)
{
 BaseContainer *src = undo->GetDataInstance();
 BaseContainer *dst = op->GetDataInstance();
 
 Vector vval = tm.off;

Vector rot = src->GetVector(DBDUB_SCA);
 switch (hit_id)
 {

case 4:
   vval.x+=src->GetVector(DBDUB_SCA).x+vval.x*0.001;
   dst->SetVector(DBDUB_SCA,Vector(FCut(vval.x,0,10000),rot.y,rot.z));
   break;
   }
 DrawViews(DA_NO_THREAD|DA_ONLY_ACTIVE_VIEW);
 return TRUE;
Thanks

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 18/09/2003 at 02:06, xxxxxxxx wrote:

ok, got it already.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/08/2009 at 13:58, xxxxxxxx wrote:

May I ask what the solution was?

I also try to implement some handles, using MoveHandle() and my handles shoot away into space if I dare move the mouse too quickly.

How did you solve it?

I want my handle to behave like the handle of the Bend deformer: I want to move the handle smoothly, like it was a normal object.

Cheers,
Jack

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/08/2009 at 14:11, xxxxxxxx wrote:

Further explanation:

I have an object with several child objects. By using handles, I want to user to move the children, without having to move select those objects in the Object Manager. So I draw a handle at each of my children, check them with DetectHandle() and return a nice handle id.

My MoveHandle() function looks like this:

> Bool MyPlugin::MoveHandle(PluginObject \*op, PluginObject \*undo, const Matrix &tm;, LONG hit_id, LONG qualifier) \> { \>      // val now contains the vector from old \>      // handle position to new handle position, right? \>      Vector val = tm.off; \> \>      // Get the child object that correlates to \>      // the handle (hit_id == 0 will get the first \>      // child, hit_id == 1 will get the second, etc) \>      BaseObject \*pobj = GetSubObjByIndex(op, hit_id); \> \>      Vector oldpos = Vector(); \>      if (pobj) oldpos = pobj->GetPos(); \>      Vector newpos = Vector(); \> \>      if (pobj) pobj->SetPos(newpos); \>      // Prevent the handle from shooting away \>      // All my efforts were futile, so far \>      newpos.x = FCut(oldpos.x + tm.off.x, 0.0f, (Real)MAXRANGE); \>      newpos.y = FCut(oldpos.y + tm.off.y, 0.0f, (Real)MAXRANGE); \>      newpos.z = FCut(oldpos.z + tm.off.z, 0.0f, (Real)MAXRANGE); \> \>      // Set the new position as position of the \>      // child object \>      if (pobj) pobj->SetPos(newpos); \> \>      return TRUE; \> }

Thanks in advance for any help!

Cheers,
Jack

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/08/2009 at 15:03, xxxxxxxx wrote:

I had no problem with this code (generally the same for three dependent objects). Kept the handle from, well, flying off the handle. 🙂

> // ObjectData.DetectHandle \> //\*---------------------------------------------------------------------------\* \> LONG MagnEtudeIPP_Zone::DetectHandle(PluginObject\* op, BaseDraw\* bd, LONG x, LONG y, LONG qualifier) \> //\*---------------------------------------------------------------------------\* \> { \>      Matrix     mg =     op->GetMg(); \> \>      if (bd->PointInRange(GetMEHandle(op,0L)\*mg,x,y))     return 0L; \>      if (bd->PointInRange(GetMEHandle(op,1L)\*mg,x,y))     return 1L; \> \>      return NOTOK; \> } \> // ObjectData.MoveHandle \> //\*---------------------------------------------------------------------------\* \> Bool MagnEtudeIPP_Zone::MoveHandle(PluginObject\* op, PluginObject\* undo, const Matrix& tm, LONG hit_id, LONG qualifier) \> //\*---------------------------------------------------------------------------\* \> { \>      BaseContainer\*     src =     undo->GetDataInstance(); \>      BaseContainer\*     dst =     op->GetDataInstance(); \> \>      // Radius \>      if (hit_id == 0L) \>      { \>           Real     val =     src->GetReal(MAGNETUDEIPP_ZONE_RADIUS)+(tm.off.x\*2.0f); \>           dst->SetReal(MAGNETUDEIPP_ZONE_RADIUS, FCut(val,0.0f,(Real)MAXRANGE)); \>      } \>      // Transparency \>      else if (hit_id == 1L) \>      { \>           Real     val =     src->GetReal(MAGNETUDEIPP_ZONE_TRANSPARENCY)+(tm.off.x\*0.01f); \>           dst->SetReal(MAGNETUDEIPP_ZONE_TRANSPARENCY, FCut(val,0.0f,1.0f)); \>      } \>      return TRUE; \> } \> // MagnEtudeIPP_Zone.GetMEHandle \> //\*---------------------------------------------------------------------------\* \> Vector MagnEtudeIPP_Zone::GetMEHandle(PluginObject\* op, const LONG& id) \> //\*---------------------------------------------------------------------------\* \> { \>      BaseContainer\*     data =          op->GetDataInstance(); \>      if (data) \>      { \>           // Radius \>           if          (id == 0L)     return Vector(data->GetReal(MAGNETUDEIPP_ZONE_RADIUS),0.0f,0.0f); \>           // Transparency \>           else if (id == 1L)     return Vector(data->GetReal(MAGNETUDEIPP_ZONE_TRANSPARENCY)\*(data->GetReal(MAGNETUDEIPP_ZONE_RADIUS)\*0.9f),0.0f,0.0f); \>      } \>      return Vector(0.0f); \> } \>

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/08/2009 at 15:26, xxxxxxxx wrote:

Hm, damn, I guess one has to use the object "undo". Since my values are not stored in the Plugin object, but are in fact positions of the children, I can't use that.

Maybe I'll have to store all the children's positions in my PluginObject class, provide a Get function and access the original positions using that function.

I'll think about it 🙂
Thanks Robert!

Cheers,
Jack

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/08/2009 at 16:26, xxxxxxxx wrote:

Strange, I can't get it to work...

I added some stuff to my class:

>      private: \>           GeAutoDynamicArray<Vector>ChildPos; \> \>      public: \>           void     SetChildPos(LONG index, Vector data)     { this->ChildPos[index] = data; } \>           Vector     GetChildPos(LONG index)                         { return this->ChildPos[index]; } \>

In GetVirtualObjects() I fill the array with the child objects' positions.

In MoveHandle() I try the following:

> \> Bool OSurfaceWire::MoveHandle(PluginObject \*op, PluginObject \*undo, const Matrix &tm;, LONG hit_id, LONG qualifier) \> { \>      Vector val = tm.off; \> \>      BaseObject \*pobj = GetSubObjByIndex(op, hit_id); \> \>      // Get stored position from "undo" object \>      // ->CRASH! \>      Vector oldpos = ((OSurfaceWire\* )undo)->GetChildPos(hit_id); \>      Vector newpos = Vector(); \>      newpos.x = FCut(oldpos.x + tm.off.x, 0.0f, Len(oldpos)); \>      newpos.y = FCut(oldpos.y + tm.off.y, 0.0f, Len(oldpos)); \>      newpos.z = FCut(oldpos.z + tm.off.z, 0.0f, Len(oldpos)); \> \>      if (pobj) pobj->SetPos(newpos); \> \>      return TRUE; \> } \>

Since it crashes in the lined I marked, I thought I would maybe have to pass the private GeAutoDynamicArray in the CopyTo() function:

> Bool OSurfaceWire::CopyTo(NodeData\* dest, GeListNode\* snode, GeListNode\* dnode, LONG flags, AliasTrans\* trn) \> { \>      LONG size = sizeof(ChildPos); \>      if(!(((OSurfaceWire\* )dest)->SplineMemory = (SplineObject\* )GeAlloc(size))) return FALSE; \>      CopyMem(this->ChildPos, ((OSurfaceWire\* )dest)->ChildPos, size); \>      return TRUE; \> } \>

The function is called, but it has no effect. MoveHandle() still crashes 😞

So, how can I apply the handle's movement to child objects of my plugin object?

Thanks again in advance!

Cheers,
Jack

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/08/2009 at 16:40, xxxxxxxx wrote:

By the way, little error in the code: Just ignore the 2nd line of the CopyTo function code.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 26/08/2009 at 06:06, xxxxxxxx wrote:

I noticed my CopyTo code was rubbish, the array was not copied (all values were 0,0,0). Now I do it like this:

> Bool OSurfaceWire::CopyTo(NodeData\* dest, GeListNode\* snode, GeListNode\* dnode, LONG flags, AliasTrans\* trn) \> { \> LONG n = ChildPos.GetCount(); \> LONG i = C_ZERO; \> \> while (i<=n) { \> ((OSurfaceWire\* )dest)->SetChildPos(i, ChildPos[i]); \> i++; \> } \> \> return TRUE; \> }

Now the array values are correctly copied into 'dest'.

Unfortunately, it seems to have nothing to do with the 'undo' object in MoveHandle(). Accessing it's GetChildPos/SetChildPos functions still crashes Cinema.

Please, any input?

Greetings,
Jack