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


Log in to reply