GeClipMap



  • On 06/01/2013 at 18:17, xxxxxxxx wrote:

    Hi Scott,
     
    Thanks for the link - there's a couple of natty little test plugins you've got there to play around with!One for the fav's list.
     
    The problem seems to occur though when a GeClipMap is used. When MSG_DESCRIPTION_GETBITMAP is called the first time, it 'seems' OK, but when it's refreshed, or you go out and back into the tab with the description element in it, Cinema crashes. When you use a plain BaseBitmap to draw with it seems fine. But I can't use that in this case. So issue seems to be with GeClipMap and custom description elements.
     
    I thought I could try making my own custom Message() to keep the draw seperate from MSG_DESCRIPTION_GETBITMAP, but didn't work. I tried using a custom function to draw the GeClipMap in and passing the drawn GeClipMap to another autoallocated bitmap, but didn't work. I tried drawing the image in the SetDParameter but it didn't seem to want to do that either. I don't know where to go from here.
     
    WP.



  • On 07/01/2013 at 02:30, xxxxxxxx wrote:

    May be try some thin like this.

      
        
        
        virtual Bool Message(GeListNode *node, LONG type, void *data)  
        {  
          if(type == MSG_DESCRIPTION_GETBITMAP)  
          {  
              DescriptionCommand *dc_Bitmap = (DescriptionCommand* )data;  
              LONG Button_Bitmap = dc_Bitmap->id[0].id;   
          
              if(Button_Bitmap == ID_TAB_TILES_PREVIEW_TILE)  
              {  
                  DescriptionGetBitmap *DGB_Bitmap = static_cast<DescriptionGetBitmap*>(data);
        
          
                  BaseBitmap *Tab_Image_Bmp = Tab_Image->GetBitmap();  
                  if(Tab_Image_Bmp!=nullptr && DGB_Bitmap->bmp!=nullptr)   
                  {  
                      Tab_Image_Bmp->CopyTo(DGB_Bitmap->bmp);  
                  }  
              }  
        
        
            }  
        }
      
    


  • On 07/01/2013 at 03:52, xxxxxxxx wrote:

    Please disregarded previous post, it's still not working correctly. I just got a warning that said my tag is not in sync. Maybe it's something else causing the problem? What does something like this mean?
     
    WP.



  • On 10/01/2013 at 20:41, xxxxxxxx wrote:

    Hi All,
     
    just giving this one a selfish bump (hope that's OK..) as I wasn't sure if anyone would've seen my updated post above.
     
    What is Cinema referring too when it says the tag is not in sync?
     
    Kind regards,
     
    WP.



  • On 11/01/2013 at 01:37, xxxxxxxx wrote:

    I think there's an error in your code. When you receive a MSG_DESCRIPTION_GETBITMAP, you're casting 'data' to a DescriptionCommand*, then using that to get the ID of the element concerned. You shouldn't do that. You need to cast it to a DescriptionGetBitmap* and use the ID from that.

    You should cast to DescriptionCommand* when you receive a MSG_DESCRIPTION_COMMAND message, but that happens when the user clicks a button. MSG_DESCRIPTION_GETBITMAP is sent by Cinema to check if the bitmap needs to be changed - it doesn't get sent on a button click.

    It may be that it doesn't matter and that the erroneous cast gives the same ID anyway, but you could change it and see what happens.

    Steve



  • On 11/01/2013 at 03:38, xxxxxxxx wrote:

    Thanks Steve,
     
    you are indeed correct that I had DescriptionCommand instead of DescriptionGetbitmap. I've changed that over, but it unfortunately hasn't made much difference. However..
     
    I took the AutoAllocated GeClipMap out from the class level and put it into my own custom function that was doing the drawing. This seems to have (albeit temporarily!!) solved my crashing problem.
     
    Not knowing a lot about what I'm doing probably means my word doesn't mean much, but it looks like either a GeClipMap bug/error, or that drawing a GeClipMap (or even referring to one) in a MSG_DESCRIPTION_GETBITMAP seems to be unstable. Of course it could still well be something else in my code. But it just seems odd to me that anywhere that Message and GeClipMap came into contact, Cinema didn't like. Particularly when I have other Bitmap buttons in my tag that seem to work fine.
     
    Thanks for your patience everyone. I'll hesitantly say I can move on...!!
     
    WP.



  • On 11/01/2013 at 04:00, xxxxxxxx wrote:

    Ehh..
    Is support able to let me/us know what this business below is about? Quoting from an error message popup I keep recieving:

    A problem with this project has been detected:
    Object "MyObject" - Tag 5712 not in sync.
    Please save and contact MAXON Support
    with a description of the last used commands, actions or plugins.
    

    WP.



  • On 11/01/2013 at 07:53, xxxxxxxx wrote:

    I'm probably way off base.
    But are you trying to use Map->BeginDraw(); from inside of your Message() function?
    I don't think we can do this.

    AFAIK. All drawing must be done within the overridden Draw() function.

    -ScottA



  • On 11/01/2013 at 14:06, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    I'm probably way off base.
    But are you trying to use Map->BeginDraw(); from inside of your Message() function?
    I don't think we can do this.

    AFAIK. All drawing must be done within the overridden Draw() function.

    -ScottA

    at least in python a GeClipMap neither provides a overrideable Draw() method, nor is it bound 
    to plugin types which provide such method.

    as a wild guess, might this be somehow conncetd to threading ? from my understanding 
    events are threaded, so there might be multiple calls to your message method at the same time.
    this might cause some problems with the memory allocation done by GeClipMap.Init() ? have you
    tried to move the whole GeClipMap code into a seperate method and just call this method
    from within Message() (the GeClipMap should then be private to this new method of course) ?

    but i am just guessing into the blue, i am most likely completely wrong :)



  • On 11/01/2013 at 15:11, xxxxxxxx wrote:

    ^I think you misunderstood.

    I never said that GeClipmap class has a Draw() function.
    What I said is there is a Draw() function available for plugins that needs to be used (overriden) when doing any drawing. And it works the same way in both Python & C++.

    For example:
    I wrote my own spline class that lets me draw custom splines on the screen. And one of things I learned when writing it is that the actual drawing must be done inside the overriden Draw() function.
    The class code can be written anywhere in the plugin. But the instance of each spline object had to be done inside of the overriden Draw() function for the drawing to work properly.
    This is also how any of the SDK drawing functions like BeginDraw(), EndDraw(), Line(),TextAT(), etc. works too.

    In short.
    In my experience. Anything drawn has to be done inside Draw().

    -ScottA



  • On 11/01/2013 at 15:28, xxxxxxxx wrote:

    hm, all i can say is, that in the plugin i am currently working on, i am using a GeUserArea which again
    has a GeClipMap as a member. All the drawing in the GeClipMap is done outisde of the Daw function
    of the GeUserArea and it is working fine. Also neither the cpp, nor the python documentation are
    mentioning something like that (that a GeClipMap is bound to overridden Draw methods).

    that was, what I meant in my first post  with :> ... , nor is it bound to plugin types which provide such method.

    or i am still misunderstanding you, then i'll have to apologize :) (language barrier and so on :) )



  • On 11/01/2013 at 15:58, xxxxxxxx wrote:

    All of my drawing experience is with drawing things on the screen or into GUI things like bitmap buttons.
    Maybe GeUserArea works differently?
    Or
    Maybe I'm just plain wrong.🙂

    All I know is that in all of my plugins. I found that I had to do any drawing from withing the overriden Draw() method for them to work. Doing them any place else would not work for me.
    I've never seen anyone else use drawing functions (other than defining them) outside of the Draw() function either. So I just accepted it as the way things work.
    In my logic. There wouldn't be a need for Maxon to include the Draw() function in the first place if it wasn't needed.
    But my logic and Maxon's logic rarely match up.😂

    -ScottA



  • On 11/01/2013 at 17:22, xxxxxxxx wrote:

    Up until now, for bitmap buttons, I was either calling the bitmap from a file inside the message, or doing all the drawing myself manually (from inside the message). All of them seemed to work except when a GeClipMap was concerned. Though admittedly, I'm not sure if any errors were present before I started this or not... I don't recall any happening. I wouldn't have thought I'd leave an error in the code laying about like that.
    Anyway, for the particular bitmapbutton ID that's causing concern, I took the bitmap draw out of Message() and made my own function which is called when the descriptions ID is called under the MSG_DESCRIPTION_GETBITMAP call. A bit like the below:

    AutoAlloc<BaseBitmap> bmp_Class;    // class level bitmap
     
    virtual Bool MyDrawFunction(void)
    {
        AutoAlloc<GeClipMap> GeCM...    // drawing made here
        bmp_Class = GeCM->GetBitmap();    // GeClipMap draw then copied to the class level bitmap
        return TRUE;
    }
     
    virtual Bool Message(GeListNode *node, LONG type, void *data)
    {
        if(type == MSG_DESCRIPTION_GETBITMAP)
        {
            DescriptionGetbitmap *MyBitmap = (DescriptionGetbitmap* )data;
            LONG Call = MyBitmap->id[0].id;
     
            if(Call == MY_BITMAP_BUTTON_ID)
            {
                DescriptionGetbitmap *gbmp = (DescriptionGetbitmap)(data)
                MyDrawFunction()
                AutoAlloc<BaseBitmap> bmp_Copy;    // new bitmap
                bmp_Copy->Init(...);    // same resolution etc as the class level bitmap
                bmp_Class->CopyTo(bmp_Copy);
                gbmp->bmp = bmp_Copy.Release();    // take image from the bitmap copy
            }
        }
        return TRUE;
    }
    

    My TagData plugin class doesn't include the virtual DRAWRESULT Draw(...) function. Should I perhaps do manual draws from there instead (not sure why I hadn't tested that actually!..)?
     
    I'm still curious to know what the error message means when it says a tag is out of sync.
     
    WP.
     
    EDIT: that Draw function wasn't what I meant there I don't think, that's for something else. Anyway hope others understand what I'm getting at there (I'm a bit fuzzed in the head from all this atm =) )..



  • On 12/01/2013 at 08:43, xxxxxxxx wrote:

    ^Not to beat a dead horse. But I really do think that Draw() is definitely what you're missing.
    Since LD brought up User Areas. I took a look at my UserArea notes. And it turns out that UA also uses an overidden draw() method to handle the live drawing. But it's named DrawMsg().
    AFAIK. We cannot draw into User Areas without it. Just like Draw() is needed for screen and GUI drawing.

    Lets think about what's happening when we are drawing something:
    We are constantly changing something(redrawing). Even if the draw values stay the same.
    What tells the plugin's GUI to keep in snyc with this drawn object?
    What happens when plugin is not there anymore but the object is still drawing itself?

    In other areas of C4D. When this sort of thing happens. Maxon uses caching.
    But when it comes to drawing things. It's been my observation that C4D uses the Draw() method to handle these situations.
    Based on my experiences. Draw() or DrawMsg() is the only place we can have our live drawing happening.
    To use the current state of the drawing in our GUI's. We MUST cache it's current state somehow so it's not constantly changing.
    To do that we use BaseBitmap or GeClipMap to save a static image(this is the cached drawing state). Which can then be used anywhere in any of the other parts of the code.
    The image can be saved to a file on the HD. Or saved into RAM memory.

    If that information is incorrect. Then I would really like Maxon to jump in here and correct me on any mistakes. Because it's all been learned by trial and error. Not from anything in the SDK.

    -ScottA



  • On 12/01/2013 at 09:48, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    ^Not to beat a dead horse. But I really do think that Draw() is definitely what you're missing.
    Since LD brought up User Areas. I took a look at my UserArea notes. And it turns out that UA also uses an overidden draw() method to handle the live drawing. But it's named DrawMsg().
    AFAIK. We cannot draw into User Areas without it. Just like Draw() is needed for screen and GUI drawing.

    of course is the drawing of the UserArea is done within DrawMsg, everything else would be 
    magic :) My GeClipMaps are just drawn once on the instantiation of the GeUserArea in its
    constructor. When c4d calls for a redraw of the UserArea, the DrawMsg() method creates a
    bitmap pattern out of the bitmaps returned by the GeClipMaps. just on certain events the
    GeClipMaps are being flushed and redrawn.

    Lets think about what's happening when we are drawing something:
    We are constantly changing something(redrawing). Even if the draw values stay the same.
    What tells the plugin's GUI to keep in snyc with this drawn object?
    What happens when plugin is not there anymore but the object is still drawing itself?

    at least for my (unexperienced) oppinion there is the basic misconecption of yours. GeClipMaps
    are not meant to be dynamic or something they are just a subtype of the c4d.Bitmap class, which 
    provides some helper methods to fill this bitmap with content. their content remains static. that is 
    the reason why there are no overwriteable methods for a GeClipMap.

    plugin classes on the other hand need a dynamic drawing content like a TagPlugin for the 
    opengl view or a GeUserArea for the gui. Because of that they have to be bound to certain 
    (overwriteable) methods. GeClipMaps are not part of the GUI, they are just static bitmaps.

    if your assumptions were true, shoud it not be impossible to use a GeClipMap in a script (or at
    least shouldn't this produce dozens of runtime errors ?).

    import c4d
    from c4d import bitmaps
    from c4d.bitmaps import GeClipMap

    w, h, step = 880, 800, 100
    txt = 'C4D'

    def main() :
        map = GeClipMap()
        map.Init(w,h)
        
        map.BeginDraw()
        map.SetColor(125,125,125,255)
        map.FillRect(0, 0, w, h)
        map.SetColor(50,50,50,255)
        for x in xrange(0, w, step) :
            for y in xrange(0, h, step) :
                map.TextAt(x, y, txt)
        map.EndDraw()
        
        bitmaps.ShowBitmap(map.GetBitmap())  
        
    if __name__=='__main__':
        main()

    or am i still misunderstanding you ? however i think i might be worth a shot for the OP, but 
    i think it is very unlikely that you are bound to Draw type methods with GeClipMaps. it would
    render GeClipMaps unuseable for large parts of the api, which might have to use a drawable
    bitmap class, but do not have any gui access.

    if i am all wrong on this, it should be stated MUCH more clearly in the documents.

    @ wicked

    i think you misunderstood me a bit. my kind of vague idea was, that the GeClipMap neither 
    should be a memeber of the plugin class, nor of the Message() method, but the member of 
    a seperate method which returns a bitmap as its result. this method is called from within
    the Message method, to ensure, that there are not any 'parallel' attempts to use the same
    GeClipMap instance in a threading context.

    but please always bring to your mind, that i am a newb :) so it is most likely utter nonsense.


Log in to reply