Tooldata plugin: DrawViews()



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

    On 17/03/2007 at 14:49, xxxxxxxx wrote:

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

    ---------
    Hi,

    I saw, that the liquid tool uses DrawViews to update the editor window. Why? Why doesn't it use EventAdd() or something? I build this call into my tool too, in order to get some speed advantages, because I only need a redraw of the active view. But

    DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION|DA_ONLY_HIGHLIGHT);

    causes a redraw of all views and all flags, not only with the DRAWFLAGS_HIGHLIGHT flag! (I checked it with a GePrint inside Draw()).

    The SDK says "Must be called from the main thread!". How can I detect whether a main thread is running? Does ToolData::GetCursorInfo(...) runs in the main thread?

    Many questions. If someone could explain, how and where to call DrawViews in a tool plugin would be very helpful. BTW: My plugin does the main stuff in GetCursorInfo not in MouseInput like the liquid tool.

    Thanks.



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

    On 17/03/2007 at 20:57, xxxxxxxx wrote:

    Don't ask me why, but DrawViews() is the standard method for tools.

    Unless you are creating a threaded plugin - it will always be the main thread so doncha worry about it - eh. :)

    Don't forget that if the tool is changing some AM attribute, you'll almost always have this combination:

    GeSyncMessage(EVMSG_TOOLCHANGED);
    DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);

    I think that the other views will naturally update (would be strange to have different states displayed wouldn't it?), but DA_ONLY_ACTIVE_VIEW limits the 'priority' view update to the active view where the tool is being used.

    I use MouseInput() exclusively and DrawViews is mainly called in the loop for win->MouseDrag(). To me, you aren't getting the mouse loop info in GetCursorInfo() which is why MouseInput() is the recommended method (the EditorWindow* win argument plays a big part here as you might surmise!). Maybe that is why you get redraws in every view - GetCursorInfo() isn't as efficient and the other views are already done updating.

    Don't rock the boat, man! ;)



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

    On 18/03/2007 at 06:49, xxxxxxxx wrote:

    You should use SpecialEventAdd(EVMSG_UPDATEHIGHLIGHT) to redraw the views from within GetCursorInfo. Don't ask why, one of the devs told me to so, after i had trouble with strange behavior.

    Maybe GetCursorInfo runs in a thread. You can probably check by calling Bool GeIsMainThread(void);

    From within MouseInput, DrawViews should work properly. I'm not sure but i think GeEventAdd just adds an EVMSG_CHANGE notification in the event queue, which won't be processed untill MouseInput returns.

    Similarly, after calling SpecialEventAdd(EVMSG_UPDATEHIGHLIGHT) the view won't be redrawn untill GetCursorInfo returns



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

    On 18/03/2007 at 07:08, xxxxxxxx wrote:

    Thanks. I have to use GetCursorInfo, because MouseInput is only called when a button key is pressed. What I'm doing are mouseover highlights (without pressing the button).

    I had changed my code to DrawViews and it works properly and I think faster than before. Before, I used EventAdd and I had trouble with C4D crashes. These crashes sometimes occured several minutes(!) later, so It was a hard work to get rid of it.

    Michael: Are you really sure that I have to change my code to SpecialEventAdd()?



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

    On 18/03/2007 at 07:25, xxxxxxxx wrote:

    OK. SpecialEventAdd(EVMSG_UPDATEHIGHLIGHT) works the same. I can't examine any difference to DrawViews. So if you recommend to use SpecialEventAdd, I do it.



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

    On 18/03/2007 at 11:47, xxxxxxxx wrote:

    This may have changed in R10, but here's how I'm doing highlighting (minus the complicated highlight draw routine since I'm highlighting polygon selections not just objects). I don't do this with GetCursorInfo(), I do it with Draw().

    // ToolData.GetCursorInfo  
    //*---------------------------------------------------------------------------*  
    Bool IPPTool::GetCursorInfo(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, Real x, Real y, BaseContainer& bc)  
    //*---------------------------------------------------------------------------*  
    {  
         bc.SetLong(RESULT_CURSOR, MOUSE_POINT_HAND);  
      
         mouseX =     x;  
         mouseY =     y;  
    #ifdef C4D_R9  
         if (x > -1.0f)     SpecialEventAdd(EVMSG_UPDATEHIGHLIGHT);  
    #else  
         if (x > -1.0f)     DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
    #endif  
      
         if (hilitedOP && hilitedBP)  
         {  
              String     selected =     hilitedOP->GetName()+":"+hilitedBP->GetName();  
              bc.SetString(RESULT_BUBBLEHELP, selected+String(opstr[operation]));  
              lastOP =     hilitedOP;  
              lastBP =     hilitedBP;  
         }  
         else  
         {  
              lastOP =     NULL;  
              lastBP =     NULL;  
              bc.SetString(RESULT_BUBBLEHELP, "interPoser Pro Tool"+String(opstr[operation]));  
         }  
         return TRUE;  
    }  
    // ToolData.Draw  
    //*---------------------------------------------------------------------------*  
    LONG IPPTool::Draw(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, BaseDrawHelp* bh, BaseThread* bt, LONG flags)  
    //*---------------------------------------------------------------------------*  
    {  
         LONG     drawFlags =                              DRAW_AXIS|DRAW_HANDLES;  
         BOOL     activeBD =                              (bd == doc->GetActiveBaseDraw());  
         // Draw Highlighting (avoids uncolored BoundingBox highlights (?))  
         // Do not highlight bodyparts if:  
         //          ActiveBaseDraw differs from this one,  
         //          We're in drag mode,  
         //          Bodypart selected and a control highlighted  
         if (activeBD && !dragMode && !restrictMode)     drawFlags =     DrawHighlights(doc, bd, bh, flags, drawFlags);  
      
         // Draw Operation Controls ONLY if there is a selection  
         if          (!selectedBP)                         return drawFlags;  
         switch (operation)  
         {  
              case IPTOP_UNIVERSAL:     DrawUniversalControl(bd, bh, activeBD);     break;  
              case IPTOP_ROTATE:          DrawRotateControl(bd, bh, activeBD);     break;  
              case IPTOP_TWIST:          DrawTwistControl(bd, bh, activeBD);          break;  
              case IPTOP_SCALE:          DrawScaleControl(bd, bh, activeBD);          break;  
              case IPTOP_TRANSLATE:     DrawTranslateControl(bd, bh, activeBD);     break;  
              default:                    break;  
         }  
         return     drawFlags &     ~DRAW_AXIS;  
    }
    

    Maybe this will help in resolving your problem (?).



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

    On 18/03/2007 at 12:59, xxxxxxxx wrote:

    Thanks for the code. It's principially the same as mine. Interesting your check for the active basedraw. Is that the currently selected view or the view where the mouse pointer is in? Why do you differ between R9 and R10 for using SpecialEventAdd resp. DrawViews? For me, SpecialEventAdd also works well in R10 (by now :-)).



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

    On 18/03/2007 at 13:07, xxxxxxxx wrote:

    All of the available views are sent for Draw() (one at a time), but I'm only interested in the active one.

    On the preprocessor directives, it's between R9+ and earlier not R9 and R10. :)



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

    On 18/03/2007 at 16:51, xxxxxxxx wrote:

    Here is some code of mine.. can't be too wrong because it works pretty well so far..

      
    Bool BaseMws::GetCursorInfo(BaseDocument *doc, BaseContainer &data;, BaseDraw *bd, Real x, Real y, BaseContainer &bc;)  
    {  
    if(bc.GetId()==BFM_CURSORINFO_REMOVE) return TRUE;  
      
    if( !PrepareTool( doc, data ) ) return FALSE;  
    if( globCache )  
    {  
        // objects and viewport and so on must always be checked for changes  
        Bool bDirty = FALSE;  
        if( !globCache->Update( doc, bd, NULL, data, bDirty ) ) return FALSE;  
      
        if( !globCache->MouseMove( x, y, TF_MOUSE, bDirty ) ) return FALSE;  
      
        if( bDirty )  
        {  
          SpecialEventAdd(EVMSG_UPDATEHIGHLIGHT);  
        }  
    }  
      
    return TRUE;  
    }  
      
    LONG BaseMws::Draw(BaseDocument *doc, BaseContainer &data;, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt,LONG flags)  
    {  
         if( !(flags&DRAWFLAGS;_HIGHLIGHT) || !globCache ) return 0;  
      
    if( globCacheAllocFunc!=GetAllocFunc( doc ) )   
    {  
        globCache.Free();  
        return 0;  
    }  
      
    // objects can change between redraws, for example when an object is deleted or modified by some  
    // hotkeyed functions while this tool is still active. When this happens, this check should  
    // protect against using invalidated data.  
    if( !globCache->CheckForDrawing( doc, bd, data ) ) return 0;  
      
    SafedDrawParam safedparam;  
    safedparam.Safe( bd );  
      
    globCache->Draw( bd, bh, bt, flags );  
      
    safedparam.Restore( bd );  
    return DRAW_HIGHLIGHTS;  
    }  
    

Log in to reply