GeClipMap
-
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 GeClipMapw, 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.