From 5518aaaace192f9d9fea351faab1acd17845e6a5 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 18 Dec 2007 21:56:17 +0000 Subject: [PATCH 01/99] Fixed bug #6711, Retopo problem when maximizing 3d view and still painting Caused by some incorrect usage of the current v3d during updates --- source/blender/src/drawview.c | 2 ++ source/blender/src/editscreen.c | 6 +----- source/blender/src/retopo.c | 7 ++----- source/blender/src/toets.c | 1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 19df0f67297..b3ffd1263ad 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3065,6 +3065,8 @@ void drawview3dspace(ScrArea *sa, void *spacedata) fdrawXORcirc((float)car[0], (float)car[1], sculptmode_brush()->size); } } + + retopo_paint_view_update(v3d); retopo_draw_paint_lines(); if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT && area_is_active_area(v3d->area)){ diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index b843d820ba5..741b6ab6d13 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -2443,9 +2443,6 @@ void area_fullscreen(void) /* with curarea */ wich_cursor(newa); } - if(curarea->full) - retopo_force_update(); - /* there's also events in queue for this, but we call fullscreen for render output now, and that doesn't go back to queue. Bad code, but doesn't hurt... (ton) */ for(sa= G.curscreen->areabase.first; sa; sa= sa->next) { @@ -2455,8 +2452,7 @@ void area_fullscreen(void) /* with curarea */ /* bad code #2: setscreen() ends with first area active. fullscreen render assumes this too */ curarea= sc->areabase.first; - if(!curarea->full) - retopo_force_update(); + retopo_force_update(); } static void area_autoplayscreen(void) diff --git a/source/blender/src/retopo.c b/source/blender/src/retopo.c index 287909da470..60be622e3ad 100644 --- a/source/blender/src/retopo.c +++ b/source/blender/src/retopo.c @@ -452,11 +452,8 @@ void retopo_force_update() if(vd) { if(vd->depths) vd->depths->damaged= 1; retopo_queue_updates(vd); - if(retopo_mesh_paint_check() && vd->retopo_view_data) { - /* Force redraw */ - drawview3dspace(vd->area, vd); - retopo_paint_view_update(vd); - } + if(retopo_mesh_paint_check() && vd->retopo_view_data) + allqueue(REDRAWVIEW3D, 0); } } } diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 27a39537988..f2c50ffc2a4 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -384,7 +384,6 @@ void persptoetsen(unsigned short event) if(G.vd->depths) G.vd->depths->damaged= 1; retopo_queue_updates(G.vd); - retopo_force_update(); if(preview3d_event) BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); From 592ed2c812bb760109ded411cf4616d84979f90d Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 18 Dec 2007 23:27:26 +0000 Subject: [PATCH 02/99] Fixed bug #7960, Sculpt Mode: Crash after Scaling brush to 1 ("Tile" mode) Division by zero fix --- source/blender/src/sculptmode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c index 8afd1dafd6a..7dd668e1acb 100644 --- a/source/blender/src/sculptmode.c +++ b/source/blender/src/sculptmode.c @@ -857,8 +857,10 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin px= len * cos(angle) + 2000; py= len * sin(angle) + 2000; } - px %= sx-1; - py %= sy-1; + if(sx != 1) + px %= sx-1; + if(sy != 1) + py %= sy-1; p= get_texcache_pixel(ss, tcw*px/sx, tch*py/sy); } else { float fx= (pv.co[0] - e->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2; From 0b66838f401f7d70c9fb187032bbb58becd66b61 Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Wed, 19 Dec 2007 05:37:57 +0000 Subject: [PATCH 03/99] Add support for stampinfo to the JPEG format. This is the review of the patch: [#5485] Invisibly stamp render information into jpg and png files. by Rob Hausauer (paprmh) NOTE: I split this patch in 3 part: 1) jpeg support 2) python api 3) sequence plugin This is the first part, hope finish with the other two tomorrow night. --- source/blender/imbuf/intern/jpeg.c | 92 +++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c index 1774aa7c156..eab07c19265 100644 --- a/source/blender/imbuf/intern/jpeg.c +++ b/source/blender/imbuf/intern/jpeg.c @@ -41,6 +41,7 @@ #include "imbuf_patch.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_imginfo.h" #include "IMB_jpeg.h" #include "jpeglib.h" @@ -244,11 +245,14 @@ static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int f int x, y, depth, r, g, b, k; struct ImBuf * ibuf = 0; uchar * rect; + jpeg_saved_marker_ptr marker; + char *str, *key, *value; /* install own app1 handler */ ibuf_ftype = 0; jpeg_set_marker_processor(cinfo, 0xe1, handle_app1); cinfo->dct_method = JDCT_FLOAT; + jpeg_save_markers(cinfo, JPEG_COM, 0xffff); if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) { x = cinfo->image_width; @@ -335,6 +339,64 @@ static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int f } } } + + marker= cinfo->marker_list; + while(marker) { + if(marker->marker != JPEG_COM) + goto next_stamp_marker; + + /* + * Because JPEG format don't support the + * pair "key/value" like PNG, we store the + * stampinfo in a single "encode" string: + * "Blender:key:value" + * + * That is why we need split it to the + * common key/value here. + */ + if(strncmp((char *) marker->data, "Blender", 7)) { + /* + * Maybe the file have text that + * we don't know "what it's", in that + * case we keep the text (with a + * key "None"). + * This is only for don't "lose" + * the information when we write + * it back to disk. + */ + IMB_imginfo_add_field(ibuf, "None", (char *) marker->data); + ibuf->flags |= IB_imginfo; + goto next_stamp_marker; + } + + str = BLI_strdup ((char *) marker->data); + key = strchr (str, ':'); + /* + * A little paranoid, but the file maybe + * is broken... and a "extra" check is better + * that a segfaul ;) + */ + if (!key) { + MEM_freeN(str); + goto next_stamp_marker; + } + + key++; + value = strchr (key, ':'); + if (!value) { + MEM_freeN(str); + goto next_stamp_marker; + } + + *value = '\0'; /* need finish the key string */ + value++; + IMB_imginfo_add_field(ibuf, key, value); + ibuf->flags |= IB_imginfo; + MEM_freeN(str); +next_stamp_marker: + marker= marker->next; + } + jpeg_finish_decompress(cinfo); } @@ -391,7 +453,8 @@ static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf) uchar * rect; int x, y; char neogeo[128]; - + ImgInfo *iptr; + char *text; jpeg_start_compress(cinfo, TRUE); @@ -401,6 +464,33 @@ static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf) memcpy(neogeo + 6, &ibuf_ftype, 4); jpeg_write_marker(cinfo, 0xe1, (JOCTET*) neogeo, 10); + if(ibuf->img_info) { + /* key + max value + "Blender" */ + text= MEM_mallocN(530, "stamp info read"); + iptr= ibuf->img_info; + while(iptr) { + if (!strcmp (iptr->key, "None")) { + jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) iptr->value, strlen (iptr->value) + 1); + goto next_stamp_info; + } + + /* + * The JPEG format don't support a pair "key/value" + * like PNG, so we "encode" the stamp in a + * single string: + * "Blender:key:value" + * + * The first "Blender" is a simple identify to help + * in the read process. + */ + sprintf (text, "Blender:%s:%s", iptr->key, iptr->value); + jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, strlen (text)+1); +next_stamp_info: + iptr = iptr->next; + } + MEM_freeN(text); + } + row_pointer[0] = mallocstruct(JSAMPLE, cinfo->input_components * From b3ff38cacdb497df769d44546416cb49bf421677 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Dec 2007 07:44:37 +0000 Subject: [PATCH 04/99] Problem with OBJ import found by Mark Ivey - would not import an obj if all verts were int values. --- release/scripts/import_obj.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py index 30c4c410434..e5bdc796e16 100644 --- a/release/scripts/import_obj.py +++ b/release/scripts/import_obj.py @@ -542,6 +542,9 @@ def get_float_func(filepath): return lambda f: float(f.replace(',', '.')) elif '.' in line: return float + + # incase all vert values were ints + return float def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS= True, CREATE_EDGES= True, SPLIT_OBJECTS= True, SPLIT_GROUPS= True, SPLIT_MATERIALS= True, IMAGE_SEARCH=True): ''' From ef4fa972babcbf788fd70ac5f50887406ca90bac Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 19 Dec 2007 08:48:41 +0000 Subject: [PATCH 05/99] Changed the default hotkeys for playing animations to be more useful IMO (ported from AnimSys branch): * Alt-A now only plays the animation in the active space, if that space is a 3D-view. Otherwise, it plays the animation in all spaces. The old behaviour simply didn't make sense for animation editors, where you'd simply see the current-frame marker moving... * Alt-Shift-A now plays the animation in all spaces regardless of whether they are active (including 3d-views) --- source/blender/src/toets.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index f2c50ffc2a4..ad7c1b4069b 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -752,12 +752,12 @@ int blenderqread(unsigned short event, short val) case AKEY: if(textediting==0 && textspace==0) { - if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){ - play_anim(1); + if ((G.qual==LR_ALTKEY) && (curarea && curarea->spacetype==SPACE_VIEW3D)) { + play_anim(0); return 0; } - else if(G.qual==LR_ALTKEY) { - play_anim(0); + else if ((G.qual==LR_ALTKEY) || (G.qual==(LR_ALTKEY|LR_SHIFTKEY))){ + play_anim(1); return 0; } } From bbc7894dd84b71e4f7aabd337231b164765e8f9c Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 19 Dec 2007 10:03:54 +0000 Subject: [PATCH 06/99] == Action Editor - Pinned Actions Bugfix == When using a pinned action, "Add New" now makes a new action. This new action is only assigned to the current Action Editor (i.e. not to any active object, as one might not exist, or might not be the object that the action is related to). --- source/blender/src/headerbuttons.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 18bbba89ce8..505206ed6e0 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -938,14 +938,14 @@ void do_global_buttons(unsigned short event) break; act=ob->action; id= (ID *)act; - + if (G.saction->actnr== -2){ activate_databrowse((ID *)G.saction->action, ID_AC, 0, B_ACTIONBROWSE, &G.saction->actnr, do_global_buttons); return; } - + if(G.saction->actnr < 0) break; - + /* See if we have selected a valid action */ for (idtest= G.main->action.first; idtest; idtest= idtest->next) { if(nr==G.saction->actnr) { @@ -956,7 +956,16 @@ void do_global_buttons(unsigned short event) } if(G.saction->pin) { - G.saction->action= (bAction *)idtest; + if (idtest == NULL) { + /* assign new/copy of pinned action only - messy as it doesn't assign to any obj's */ + if (G.saction->action) + G.saction->action= (bAction *)copy_action(G.saction->action); + else + G.saction->action= (bAction *)add_empty_action("PinnedAction"); + } + else { + G.saction->action= (bAction *)idtest; + } allqueue(REDRAWACTION, 0); } else { From da22572e4cf76b87951aa5edaaf87d99c315ef98 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 19 Dec 2007 10:52:26 +0000 Subject: [PATCH 07/99] == Action Editor - Long Keyframes == Now Long-Keyframes in the Action Editor (yellow/pink strips between keyframes) take into account whether the keyframe handles which help control the interpolation between the two keyframes stay at the same value as the keyframes do. This way, long keyframes are not drawn when the keys have the same value, but there's still movement between them. --- source/blender/src/drawaction.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 3cfe3731367..6cda5e69ea7 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -1045,11 +1045,14 @@ static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index } } - /* check if block needed - same value? */ - if ((!prev) || (!beztn)) - return; - if (beztn->vec[1][1] != prev->vec[1][1]) - return; + /* check if block needed - same value(s)? + * -> firstly, handles must have same central value as each other + * -> secondly, handles which control that section of the curve must be constant + */ + if ((!prev) || (!beztn)) return; + if (IS_EQ(beztn->vec[1][1], prev->vec[1][1])==0) return; + if (IS_EQ(beztn->vec[1][1], beztn->vec[0][1])==0) return; + if (IS_EQ(prev->vec[1][1], prev->vec[2][1])==0) return; /* try to find a keyblock that starts on the previous beztriple */ for (ab= blocks->first; ab; ab= ab->next) { From 42f80b30376f0de1569b3a06d33e912dc071dfc5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 19 Dec 2007 12:12:38 +0000 Subject: [PATCH 08/99] Bugfix for hinge bone transform for multiple selected bones: now only transforms the children too if they are connected, otherwise they get transformed twice. --- source/blender/src/transform_conversions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index bde79b068dd..405168f6654 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -626,7 +626,7 @@ static void bone_children_clear_transflag(ListBase *lb) Bone *bone= lb->first; for(;bone;bone= bone->next) { - if(bone->flag & BONE_HINGE) + if((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) bone->flag |= BONE_HINGE_CHILD_TRANSFORM; else bone->flag &= ~BONE_TRANSFORM; From 39a99b1b05de9ddd57c6a1beb4ea5e61cc7b5322 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 19 Dec 2007 13:11:54 +0000 Subject: [PATCH 09/99] Bugfix: prevention of redraw of the 3d view or other windows while rendering to the image editor missed one case, could result in modifiers and particles being evaluated with G.rendering == 1 but still showing in the viewport. --- source/blender/src/drawimage.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index ea9dc6a0482..65ee3077adb 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -2610,7 +2610,9 @@ static void imagewindow_init_display_cb(RenderResult *rr) drawimagespace(image_area, sima); if(image_area->headertype) scrarea_do_headdraw(image_area); - screen_swapbuffers(); + + /* no screen_swapbuffers, prevent any other window to draw */ + myswapbuffers(); allqueue(REDRAWIMAGE, 0); /* redraw in end */ } From b8ca87a0baefe10317fae87528f3eb2f0bf372c2 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Wed, 19 Dec 2007 18:17:56 +0000 Subject: [PATCH 10/99] Rendering -------- Bugfix #4863: AVI jpg would crash on really small images (less than 16x16). Change it to pop up an error dialog and abort. --- source/blender/render/intern/source/pipeline.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index da2542aabaa..0f9d4470164 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1046,7 +1046,8 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect re->recty= winy; } - if(re->rectx < 2 || re->recty < 2) { + if(re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->imtype) && +(re->rectx < 16 || re->recty < 16) )) { re->error("Image too small"); re->ok= 0; } @@ -2197,6 +2198,8 @@ static int render_initialize_from_scene(Render *re, Scene *scene) push_render_result(re); RE_InitState(re, &scene->r, winx, winy, &disprect); + if(!re->ok) /* if an error was printed, abort */ + return 0; /* initstate makes new result, have to send changed tags around */ ntreeCompositTagRender(re->scene); From 361d23224c356aa46769a0b8102752d757231df8 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 19 Dec 2007 22:37:38 +0000 Subject: [PATCH 11/99] == Action Editor - Copy/Paste == Now the Copy/Paste functionality stores more info about where keyframes came from. This allows users to copy full poses in the Action Editor and paste them in another action. Peach request/bugfix for William. --- source/blender/src/editaction.c | 204 ++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 63 deletions(-) diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index dc13e5d3019..c9e2df8d9eb 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -1144,10 +1144,9 @@ void clean_action (void) /* **************************************************** */ /* COPY/PASTE FOR ACTIONS */ -/* - The copy/paste buffer currently stores a set of IPO curves, with no - * repeating curve-types (i.e. no curves with the same adrcode). - * - Only selected keyframes from the source curves are placed here. - * - Only 'compatible' pastes are done. +/* - The copy/paste buffer currently stores a set of Action Channels, with temporary + * IPO-blocks, and also temporary IpoCurves which only contain the selected keyframes. + * - Only pastes between compatable data is possible (i.e. same achan->name, ipo-curve type, etc.) */ /* globals for copy/paste data (like for other copy/paste buffers) */ @@ -1156,16 +1155,34 @@ ListBase actcopybuf = {NULL, NULL}; /* This function frees any MEM_calloc'ed copy/paste buffer data */ void free_actcopybuf () { - IpoCurve *icu; + bActionChannel *achan, *anext; + bConstraintChannel *conchan, *cnext; - while( (icu= actcopybuf.first) ) { - BLI_remlink(&actcopybuf, icu); - free_ipo_curve(icu); + for (achan= actcopybuf.first; achan; achan= next) { + next= achan->next; + + if (achan->ipo) { + free_ipo(achan->ipo); + MEM_freeN(achan->ipo); + } + + for (conchan=achan->constraintChannels.first; conchan; conchan=cnext) { + cnext= conchan->next; + + if (conchan->ipo) { + free_ipo(conchan->ipo); + MEM_freeN(conchan->ipo); + } + + BLI_freelistN(&achan->constraintChannels, conchan); + } + + BLI_freelinkN(&actcopybuf, achan); } } /* This function adds data to the copy/paste buffer, freeing existing data first - * Only the active action channel gets its selected keyframes copied. + * Only the selected action channels gets their selected keyframes copied. */ void copy_actdata () { @@ -1183,40 +1200,61 @@ void copy_actdata () if (data == NULL) return; /* filter data */ - filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_ONLYICU); + filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_IPOKEYS); actdata_filter(&act_data, filter, data, datatype); - /* each of these entries should be an ipo curve */ + /* assume that each of these is an ipo-block */ for (ale= act_data.first; ale; ale= ale->next) { - IpoCurve *icu= ale->key_data; - IpoCurve *icn; + bActionChannel *achan; + Ipo *ipo= ale->key_data; + Ipo *ipn; + IpoCurve *icu, *icn; BezTriple *bezt; - short nin_buffer= 1; int i; - /* check if a curve like this exists already in buffer */ - for (icn= actcopybuf.first; icn; icn= icn->next) { - if ((icn->blocktype==icu->blocktype) && (icn->adrcode==icu->adrcode)) { - nin_buffer= 0; - break; - } + /* coerce an action-channel out of owner */ + if (ale->ownertype == ACTTYPE_ACHAN) { + bActionChannel *achanO= ale->owner; + achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan"); + strcpy(achan->name, achanO->name); } - /* allocate memory for a new curve if a valid one wasn't found */ - if (nin_buffer) { - icn= MEM_callocN(sizeof(IpoCurve), "actcopybuf"); - - *icn= *icu; - icn->totvert= 0; - icn->bezt = NULL; - icn->driver = NULL; - - BLI_addtail(&actcopybuf, icn); + else if (ale->ownertype == ACTTYPE_SHAPEKEY) { + achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan"); + strcpy(achan->name, "#ACP_ShapeKey"); } + else + continue; + BLI_addtail(&actcopybuf, achan); - /* find selected BezTriples to add to the buffer */ - for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { - if (BEZSELECTED(bezt)) - insert_bezt_icu(icn, bezt); + /* add constraint channel if needed, then add new ipo-block */ + if (ale->type == ACTTYPE_CONCHAN) { + bConstraintChannel *conchanO= ale->data; + bConstraintChannel *conchan; + + conchan= MEM_callocN(sizeof(bConstraintChannel), "ActCopyPasteConchan"); + strcpy(conchan->name, conchanO->name); + BLI_addtail(&achan->constraintChannels, conchan); + + conchan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo"); + } + else { + achan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo"); + } + ipn->blocktype = ipo->blocktype; + + /* now loop through curves, and only copy selected keyframes */ + for (icu= ipo->curve.first; icu; icu= icu->next) { + /* allocate a new curve */ + icn= MEM_callocN(sizeof(IpoCurve), "ActCopyPasteIcu"); + icn->blocktype = icu->blocktype; + icn->adrcode = icu->adrcode; + BLI_addtail(&ipn->curve, icn); + + /* find selected BezTriples to add to the buffer */ + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + if (BEZSELECTED(bezt)) + insert_bezt_icu(icn, bezt); + } } } @@ -1247,48 +1285,88 @@ void paste_actdata () if (data == NULL) return; /* filter data */ - filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU); + filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS); actdata_filter(&act_data, filter, data, datatype); /* from selected channels */ for (ale= act_data.first; ale; ale= ale->next) { - IpoCurve *icu= ale->key_data; - IpoCurve *ico; + Ipo *ipo_src=NULL, *ipo_dst=ale->key_data; + bActionChannel *achan; + IpoCurve *ico, *icu; BezTriple *bezt; int i; float offset= 0.0f; short offsetInit= 1; - /* find matching ipo-curve */ - for (ico= actcopybuf.first; ico; ico= ico->next) { - if ((ico->blocktype==icu->blocktype) && (ico->adrcode==icu->adrcode)) { - /* just start pasting, with the the first keyframe on the current frame, and so on */ - for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) { - /* initialise offset (if not already done) */ - if (offsetInit) { - offset= CFRA - bezt->vec[1][0]; - offsetInit= 0; + /* find matching ipo-block */ + for (achan= actcopybuf.first; achan; achan= achan->next) { + /* try to match data */ + if (ale->ownertype == ACTTYPE_ACHAN) { + bActionChannel *achant= ale->owner; + + /* check if we have a corresponding action channel */ + if (strcmp(achan->name, achant->name)==0) { + /* check if this is a constraint channel */ + if (ale->type == ACTTYPE_CONCHAN) { + bConstraintChannel *conchant= ale->data; + bConstraintChannel *conchan; + + for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) { + if (strcmp(conchan->name, conchant->name)==0) { + ipo_src= conchan->ipo; + break; + } + } + if (ipo_src) break; + } + else { + ipo_src= achan->ipo; + break; + } + } + } + else if (ale->ownertype == ACTTYPE_SHAPEKEY) { + /* check if this action channel is "#ACP_ShapeKey" */ + if (strcmp(achan->name, "#ACP_ShapeKey")==0) { + ipo_src= achan->ipo; + break; + } + } + } + + /* loop over curves, pasting keyframes */ + for (icu= ipo_dst->curve.first; icu; icu= icu->next) { + for (ico= ipo_src->curve.first; ico; ico= ico->next) { + /* only paste if compatable blocktype + adrcode */ + if ((ico->blocktype==icu->blocktype) && (ico->adrcode==icu->adrcode)) { + /* just start pasting, with the the first keyframe on the current frame, and so on */ + for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) { + /* initialise offset (if not already done) */ + if (offsetInit) { + offset= CFRA - bezt->vec[1][0]; + offsetInit= 0; + } + + /* temporarily apply offset to src beztriple while copying */ + bezt->vec[0][0] += offset; + bezt->vec[1][0] += offset; + bezt->vec[2][0] += offset; + + /* insert the keyframe */ + insert_bezt_icu(icu, bezt); + + /* un-apply offset from src beztriple after copying */ + bezt->vec[0][0] -= offset; + bezt->vec[1][0] -= offset; + bezt->vec[2][0] -= offset; } - /* temporarily apply offset to src beztriple while copying */ - bezt->vec[0][0] += offset; - bezt->vec[1][0] += offset; - bezt->vec[2][0] += offset; + /* recalculate channel's handles? */ + calchandles_ipocurve(icu); - /* insert the keyframe */ - insert_bezt_icu(icu, bezt); - - /* un-apply offset from src beztriple after copying */ - bezt->vec[0][0] -= offset; - bezt->vec[1][0] -= offset; - bezt->vec[2][0] -= offset; + /* done for this channel */ + break; } - - /* recalculate channel's handles? */ - calchandles_ipocurve(icu); - - /* done for this channel */ - break; } } } From 2a43932a74586ea5c88637d423e93ffb350d4074 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Wed, 19 Dec 2007 23:14:14 +0000 Subject: [PATCH 12/99] == Imbuf == The TIFF reader did error handling with assert which is a pretty bad idea (tm). This fixes the assert-crash, that the TIFF reader triggers, if one tries to open a RAW-DV file within the compositor. (File extension is only two characters long, which is enough for an assert... EVEN IF IT ISN'T A TIFF FILE, WE ARE GOING TO OPEN. GRMBL) Removed all other assertions and added proper error handling. (using STDERR, where it belongs.) --- source/blender/imbuf/intern/tiff.c | 60 +++++++++++++++++++----------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 6fc5fb99f8b..42c8ddb7d38 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -43,7 +43,6 @@ * used to compress images. */ -#include #include #include "imbuf.h" @@ -108,7 +107,6 @@ int imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) * * @return: Number of bytes actually read. * 0 = EOF. - * -1 = Error (never returned). */ tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n) { @@ -118,8 +116,10 @@ tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n) /* get the pointer to the in-memory file */ mfile = IMB_TIFF_GET_MEMFILE(handle); - assert(mfile != NULL); - assert(mfile->mem != NULL); + if (!mfile || !mfile->mem) { + fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n"); + return 0; + } /* find the actual number of bytes to read (copy) */ nCopy = n; @@ -136,7 +136,6 @@ tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n) return (0); /* all set -> do the read (copy) */ - assert(sizeof(unsigned char) == 1); srcAddr = (void*)(&(mfile->mem[mfile->offset])); memcpy((void*)data, srcAddr, nCopy); mfile->offset += nCopy; /* advance file ptr by copied bytes */ @@ -180,8 +179,10 @@ toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence) /* get the pointer to the in-memory file */ mfile = IMB_TIFF_GET_MEMFILE(handle); - assert(mfile != NULL); - assert(mfile->mem != NULL); + if (!mfile || !mfile->mem) { + fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n"); + return (-1); + } /* find the location we plan to seek to */ switch (whence) { @@ -193,7 +194,9 @@ toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence) break; default: /* no other types are supported - return an error */ - printf("Unsupported TIFF SEEK type.\n"); + fprintf(stderr, + "imb_tiff_SeekProc: " + "Unsupported TIFF SEEK type.\n"); return (-1); } @@ -222,8 +225,10 @@ int imb_tiff_CloseProc(thandle_t handle) /* get the pointer to the in-memory file */ mfile = IMB_TIFF_GET_MEMFILE(handle); - assert(mfile != NULL); - assert(mfile->mem != NULL); /* the file has not been closed yet */ + if (!mfile || !mfile->mem) { + fprintf(stderr,"imb_tiff_CloseProc: !mfile || !mfile->mem!\n"); + return (0); + } /* virtually close the file */ mfile->mem = NULL; @@ -246,8 +251,10 @@ toff_t imb_tiff_SizeProc(thandle_t handle) /* get the pointer to the in-memory file */ mfile = IMB_TIFF_GET_MEMFILE(handle); - assert(mfile != NULL); - assert(mfile->mem != NULL); + if (!mfile || !mfile->mem) { + fprintf(stderr,"imb_tiff_SizeProc: !mfile || !mfile->mem!\n"); + return (0); + } /* return the size */ return (toff_t)(mfile->size); @@ -317,7 +324,10 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags) memFile.size = size; /* check whether or not we have a TIFF file */ - assert(size >= IMB_TIFF_NCB); + if (size < IMB_TIFF_NCB) { + fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n"); + return NULL; + } if (imb_is_a_tiff(mem) == 0) return NULL; @@ -340,7 +350,8 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags) if (ibuf) { ibuf->ftype = TIF; } else { - printf("imb_loadtiff: could not allocate memory for TIFF " \ + fprintf(stderr, + "imb_loadtiff: could not allocate memory for TIFF " \ "image.\n"); libtiff_TIFFClose(image); return NULL; @@ -362,7 +373,8 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags) success = libtiff_TIFFReadRGBAImage( image, width, height, raster, 0); if (!success) { - printf("imb_loadtiff: This TIFF format is not " \ + fprintf(stderr, + "imb_loadtiff: This TIFF format is not " "currently supported by Blender.\n"); libtiff__TIFFfree(raster); libtiff_TIFFClose(image); @@ -378,7 +390,8 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags) /* this may not be entirely necessary, but is put here * in case sizeof(unsigned int) is not a 32-bit * quantity */ - printf("imb_loadtiff: using (slower) component-wise " \ + fprintf(stderr, + "imb_loadtiff: using (slower) component-wise " "buffer copy.\n"); to = (unsigned char*)ibuf->rect; for (pixel_i=0; pixel_i < width*height; pixel_i++) @@ -437,7 +450,8 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags) * to gray, RGB, RGBA respectively. */ samplesperpixel = (uint16)((ibuf->depth + 7) >> 3); if ((samplesperpixel > 4) || (samplesperpixel == 2)) { - printf("imb_savetiff: unsupported number of bytes per " \ + fprintf(stderr, + "imb_savetiff: unsupported number of bytes per " "pixel: %d\n", samplesperpixel); return (0); } @@ -445,7 +459,8 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags) /* open TIFF file for writing */ if (flags & IB_mem) { /* bork at the creation of a TIFF in memory */ - printf("imb_savetiff: creation of in-memory TIFF files is " \ + fprintf(stderr, + "imb_savetiff: creation of in-memory TIFF files is " "not yet supported.\n"); return (0); } else { @@ -453,7 +468,8 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags) image = libtiff_TIFFOpen(name, "w"); } if (image == NULL) { - printf("imb_savetiff: could not open TIFF for writing.\n"); + fprintf(stderr, + "imb_savetiff: could not open TIFF for writing.\n"); return (0); } @@ -462,7 +478,8 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags) pixels = (unsigned char*)libtiff__TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned char)); if (pixels == NULL) { - printf("imb_savetiff: could not allocate pixels array.\n"); + fprintf(stderr, + "imb_savetiff: could not allocate pixels array.\n"); libtiff_TIFFClose(image); return (0); } @@ -533,7 +550,8 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags) libtiff_TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); if (libtiff_TIFFWriteEncodedStrip(image, 0, pixels, ibuf->x*ibuf->y*samplesperpixel) == -1) { - printf("imb_savetiff: Could not write encoded TIFF.\n"); + fprintf(stderr, + "imb_savetiff: Could not write encoded TIFF.\n"); libtiff_TIFFClose(image); libtiff__TIFFfree(pixels); return (1); From 0a682cb50fe46a0e4327546cb74370c8e88fa231 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 19 Dec 2007 23:29:42 +0000 Subject: [PATCH 13/99] == Action Editor - Show Hidden Channels == This option (found in the View menu) shows all Action Channels, regardless of whether the data they represent is visible or not. It's better than having to have multiple pinned Action Editors open to be able to move all keyframes of all bones at once (when blocking for example). Also, fixed some compile errors caused by previous commit... --- source/blender/makesdna/DNA_action_types.h | 4 +++- source/blender/src/drawaction.c | 4 ++-- source/blender/src/editaction.c | 6 +++--- source/blender/src/header_action.c | 9 +++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 707460d0fb6..db6a2bda53c 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -154,7 +154,9 @@ typedef enum SACTION_FLAG { /* show sliders (if relevant) */ SACTION_SLIDERS = (1<<1), /* draw time in seconds instead of time in frames */ - SACTION_DRAWTIME = (1<<2) + SACTION_DRAWTIME = (1<<2), + /* don't filter action channels according to visibility */ + SACTION_NOHIDE = (1<<3) } SACTION_FLAG; /* SpaceAction AutoSnap Settings (also used by SpaceNLA) */ diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 6cda5e69ea7..58dfdd89df2 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -617,12 +617,12 @@ void check_action_context(SpaceAction *saction) { bActionChannel *achan; - if(saction->action==NULL) return; + if (saction->action==NULL) return; for (achan=saction->action->chanbase.first; achan; achan=achan->next) achan->flag &= ~ACHAN_HIDDEN; - if (G.saction->pin==0 && OBACT) { + if ((saction->pin==0) && ((saction->flag & SACTION_NOHIDE)==0) && (OBACT)) { Object *ob= OBACT; bPoseChannel *pchan; bArmature *arm= ob->data; diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index c9e2df8d9eb..cb032ddfb61 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -1158,8 +1158,8 @@ void free_actcopybuf () bActionChannel *achan, *anext; bConstraintChannel *conchan, *cnext; - for (achan= actcopybuf.first; achan; achan= next) { - next= achan->next; + for (achan= actcopybuf.first; achan; achan= anext) { + anext= achan->next; if (achan->ipo) { free_ipo(achan->ipo); @@ -1174,7 +1174,7 @@ void free_actcopybuf () MEM_freeN(conchan->ipo); } - BLI_freelistN(&achan->constraintChannels, conchan); + BLI_freelinkN(&achan->constraintChannels, conchan); } BLI_freelinkN(&actcopybuf, achan); diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index 6d01dcf6bab..9e858cb8307 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -93,6 +93,7 @@ enum { ACTMENU_VIEW_NEXTMARKER, ACTMENU_VIEW_PREVMARKER, ACTMENU_VIEW_TIME, + ACTMENU_VIEW_NOHIDE }; enum { @@ -299,6 +300,9 @@ static void do_action_viewmenu(void *arg, int event) case ACTMENU_VIEW_TIME: /* switch between frames and seconds display */ G.saction->flag ^= SACTION_DRAWTIME; break; + case ACTMENU_VIEW_NOHIDE: /* Show hidden channels */ + G.saction->flag ^= SACTION_NOHIDE; + break; } allqueue(REDRAWVIEW3D, 0); } @@ -340,6 +344,11 @@ static uiBlock *action_viewmenu(void *arg_unused) menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_VIEW_SLIDERS, ""); + uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NOHIDE)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, + "Show Hidden Channels|", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, + ACTMENU_VIEW_NOHIDE, ""); + uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT, "Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, From 5925fe36e0a176a73e65950f7ed5eef510c12f02 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 20 Dec 2007 10:27:13 +0000 Subject: [PATCH 14/99] Render-farm and file utils for dealing with external data. Useful to use before sending blend files to the renderfarm. * Make all Paths Relative - makes any absolute paths relative. * Report Missing Files - creates a textblock listing all missing files. * Find Missing Files - searches a directory recursively for filenames that dont exist at their current path. Added a path looper type and functions that currently loop on image, sound, font and external library paths. --- source/blender/blenlib/BLI_boxpack2d.h | 5 +- source/blender/blenlib/BLI_bpath.h | 59 +++ source/blender/blenlib/intern/bpath.c | 485 +++++++++++++++++++++++++ source/blender/src/header_info.c | 100 ++++- 4 files changed, 626 insertions(+), 23 deletions(-) create mode 100644 source/blender/blenlib/BLI_bpath.h create mode 100644 source/blender/blenlib/intern/bpath.c diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack2d.h index b5cf9cd81e9..50b864df5f8 100644 --- a/source/blender/blenlib/BLI_boxpack2d.h +++ b/source/blender/blenlib/BLI_boxpack2d.h @@ -28,10 +28,7 @@ * Contributor(s): Campbell Barton * * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * - * The old math stuff from Ton. These will slowly phase out in favour - * of MTC calls. (or even MoTO :) ) - * */ + */ /* Box Packer */ diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h new file mode 100644 index 00000000000..e2d7d23410c --- /dev/null +++ b/source/blender/blenlib/BLI_bpath.h @@ -0,0 +1,59 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* Based on ghash, difference is ghash is not a fixed size, + * so for BPath we dont need to malloc */ + +struct BPathIterator { + char* path; + char* lib; + char* name; + void* data; + int len; + int type; +}; + +void BLI_bpathIterator_init (struct BPathIterator *bpi); +char* BLI_bpathIterator_getPath (struct BPathIterator *bpi); +char* BLI_bpathIterator_getLib (struct BPathIterator *bpi); +char* BLI_bpathIterator_getName (struct BPathIterator *bpi); +int BLI_bpathIterator_getType (struct BPathIterator *bpi); +int BLI_bpathIterator_getPathMaxLen(struct BPathIterator *bpi); +void BLI_bpathIterator_step (struct BPathIterator *bpi); +int BLI_bpathIterator_isDone (struct BPathIterator *bpi); +void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded); + +/* high level funcs */ + +/* creates a text file with missing files if there are any */ +struct Text * checkMissingFiles(void); +void makeFilesRelative(int *tot, int *changed, int *failed, int *linked); +void findMissingFiles(char *str); diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c new file mode 100644 index 00000000000..598b5720b65 --- /dev/null +++ b/source/blender/blenlib/intern/bpath.c @@ -0,0 +1,485 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell barton + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "BLI_bpath.h" +#include "BKE_global.h" +#include "DNA_ID.h" /* Library */ +#include "DNA_vfont_types.h" +#include "DNA_image_types.h" +#include "DNA_sound_types.h" +#include "DNA_scene_types.h" /* to get the current frame */ +#include +#include + +#include "BKE_main.h" /* so we can access G.main->*.first */ +#include "BKE_image.h" /* so we can check the image's type */ + +#include "blendef.h" +#include "BKE_utildefines.h" + +/* for writing to a textblock */ +#include "BKE_text.h" +#include "BLI_blenlib.h" +#include "DNA_text_types.h" + +/* path/file handeling stuff */ +#ifndef WIN32 + #include +#else + #include "BLI_winstuff.h" +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define FILE_MAX 240 + + +/* TODO - BPATH_PLUGIN, BPATH_SEQ */ +enum BPathTypes { + BPATH_IMAGE = 0, + BPATH_SOUND, + BPATH_FONT, + BPATH_LIB, + + BPATH_DONE +}; + + +void BLI_bpathIterator_init( struct BPathIterator *bpi ) { + bpi->type = BPATH_IMAGE; + bpi->data = NULL; + BLI_bpathIterator_step(bpi); +} + +char* BLI_bpathIterator_getPath( struct BPathIterator *bpi) { + return bpi->path; +} +void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded) { + char *filepath, *libpath; + + filepath = BLI_bpathIterator_getPath(bpi); + libpath = BLI_bpathIterator_getLib(bpi); + + BLI_strncpy(path_expanded, filepath, FILE_MAXDIR*2); + + if (libpath) { /* check the files location relative to its library path */ + BLI_convertstringcode(path_expanded, libpath, G.scene->r.cfra); + } else { /* local data, use the blend files path */ + BLI_convertstringcode(path_expanded, G.sce, G.scene->r.cfra); + } +} +char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) { + return bpi->lib; +} +char* BLI_bpathIterator_getName( struct BPathIterator *bpi) { + return bpi->name; +} +int BLI_bpathIterator_getType( struct BPathIterator *bpi) { + return bpi->type; +} +int BLI_bpathIterator_getPathMaxLen( struct BPathIterator *bpi) { + return bpi->len; +} + +/* gets the first or the next image that has a path - not a viewer node or generated image */ +static struct Image *ima_getpath__internal(struct Image *ima, int step_next) { + if (ima==NULL) + return NULL; + + if (step_next) + ima = ima->id.next; + + while (ima) { + if (ima->packedfile==NULL && ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) + break; + /* image is not a image with a path, skip it */ + ima = ima->id.next; + } + return ima; +} + +static struct VFont *vf_getpath__internal(struct VFont *vf, int step_next) { + if (vf==NULL) + return NULL; + + if (step_next) + vf = vf->id.next; + + while (vf) { + if (vf->packedfile==NULL && BLI_streq(vf->name, "")==0) { + break; + } + + /* font with no path, skip it */ + vf = vf->id.next; + } + return vf; +} + +static struct bSound *snd_getpath__internal(struct bSound *snd, int step_next) { + if (snd==NULL) + return NULL; + + if (step_next) + snd = snd->id.next; + + while (snd) { + if (snd->packedfile==NULL) { + break; + } + + /* font with no path, skip it */ + snd = snd->id.next; + } + return snd; +} + +void BLI_bpathIterator_step( struct BPathIterator *bpi) { + while (bpi->type != BPATH_DONE) { + + if ((bpi->type) == BPATH_IMAGE) { + /*if (bpi->data) bpi->data = ((ID *)bpi->data)->next;*/ + if (bpi->data) bpi->data = ima_getpath__internal( (Image *)bpi->data, 1 ); /* must skip images that have no path */ + else bpi->data = ima_getpath__internal(G.main->image.first, 0); + + if (bpi->data) { + /* get the path info from this datatype */ + Image *ima = (Image *)bpi->data; + + bpi->lib = ima->id.lib ? ima->id.lib->filename : NULL; + bpi->path = ima->name; + bpi->name = ima->id.name+2; + bpi->len = sizeof(ima->name); + + /* we are done, advancing to the next item, this type worked fine */ + break; + + } else { + bpi->type+=1; /* advance to the next type */ + } + + + } else if ((bpi->type) == BPATH_SOUND) { + if (bpi->data) bpi->data = snd_getpath__internal( (bSound *)bpi->data, 1 ); /* must skip images that have no path */ + else bpi->data = snd_getpath__internal(G.main->sound.first, 0); + + if (bpi->data) { + /* get the path info from this datatype */ + bSound *snd = (bSound *)bpi->data; + + bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL; + bpi->path = snd->sample->name; + bpi->name = snd->id.name+2; + bpi->len = sizeof(snd->sample->name); + + /* we are done, advancing to the next item, this type worked fine */ + break; + } else { + bpi->type+=1; /* advance to the next type */ + } + + + } else if ((bpi->type) == BPATH_FONT) { + + if (bpi->data) bpi->data = vf_getpath__internal( (VFont *)bpi->data, 1 ); + else bpi->data = vf_getpath__internal( G.main->vfont.first, 0 ); + + if (bpi->data) { + /* get the path info from this datatype */ + VFont *vf = (VFont *)bpi->data; + + bpi->lib = vf->id.lib ? vf->id.lib->filename : NULL; + bpi->path = vf->name; + bpi->name = vf->id.name+2; + bpi->len = sizeof(vf->name); + + /* we are done, advancing to the next item, this type worked fine */ + break; + } else { + bpi->type+=1; /* advance to the next type */ + } + + + } else if ((bpi->type) == BPATH_LIB) { + + if (bpi->data) bpi->data = ((ID *)bpi->data)->next; + else bpi->data = G.main->library.first; + + if (bpi->data) { + /* get the path info from this datatype */ + Library *lib = (Library *)bpi->data; + + bpi->lib = NULL; + bpi->path = lib->name; + bpi->name = NULL; + bpi->len = sizeof(lib->name); + + /* we are done, advancing to the next item, this type worked fine */ + break; + } else { + bpi->type+=1; /* advance to the next type */ + } + } + } +} + +int BLI_bpathIterator_isDone( struct BPathIterator *bpi) { + return bpi->type==BPATH_DONE; +} + +/* include the path argument */ +static void bpathToText(Text *btxt, struct BPathIterator *bpi) +{ + char *name; + char path_expanded[FILE_MAXDIR*2]; + + switch(BLI_bpathIterator_getType(bpi)) { + case BPATH_IMAGE: + txt_insert_buf( btxt, "Image \"" ); + break; + case BPATH_SOUND: + txt_insert_buf( btxt, "Sound \"" ); + break; + case BPATH_FONT: + txt_insert_buf( btxt, "Font \"" ); + break; + case BPATH_LIB: + txt_insert_buf( btxt, "Library \"" ); + break; + default: + txt_insert_buf( btxt, "Unknown \"" ); + break; + } + + name = BLI_bpathIterator_getName(bpi); + + if (name) { + txt_insert_buf( btxt, name ); + } + txt_insert_buf( btxt, "\" " ); + + BLI_bpathIterator_copyPathExpanded(bpi, path_expanded); + + txt_insert_buf( btxt, path_expanded ); + txt_insert_buf( btxt, "\n" ); + txt_move_eof( btxt, 0 ); +} + +/* high level function */ +Text *checkMissingFiles(void) { + Text *btxt = NULL; + struct BPathIterator bpi; + + /* be sure there is low chance of the path being too short */ + char filepath_expanded[FILE_MAXDIR*2]; + char *filepath, *libpath; + int files_missing = 0; + + BLI_bpathIterator_init(&bpi); + while (!BLI_bpathIterator_isDone(&bpi)) { + filepath = BLI_bpathIterator_getPath(&bpi); + libpath = BLI_bpathIterator_getLib(&bpi); + + BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded ); + + if (!BLI_exists(filepath_expanded)) { + if (!btxt) + btxt = add_empty_text( "missing_files.txt" ); + + bpathToText(btxt, &bpi); + files_missing = 1; + } + BLI_bpathIterator_step(&bpi); + } + return btxt; +} + +/* dont log any errors at the moment, should probably do this */ +void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { + struct BPathIterator bpi; + char *filepath, *libpath; + + /* be sure there is low chance of the path being too short */ + char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE]; + + *tot = *changed = *failed = *linked = 0; + + BLI_bpathIterator_init(&bpi); + while (!BLI_bpathIterator_isDone(&bpi)) { + filepath = BLI_bpathIterator_getPath(&bpi); + libpath = BLI_bpathIterator_getLib(&bpi); + + if(strncmp(filepath, "//", 2)==0) { + if (libpath) { /* cant make relative if we are kibrary - TODO, LOG THIS */ + (*linked)++; + } else { /* local data, use the blend files path */ + BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative)); + BLI_makestringcode(G.sce, filepath_relative); + if (BLI_bpathIterator_getPathMaxLen(&bpi) < strlen(filepath_relative)) { + (*failed)++; + } else { + /* safe to to check the length */ + if(strncmp(filepath_relative, "//", 2)==0) { + (*failed)++; + } else { + strcpy(filepath, filepath_relative); + (*changed)++; + } + } + } + } + + BLI_bpathIterator_step(&bpi); + (*tot)++; + } +} + +/* find this file recursively, use the biggest file so thumbnails dont get used by mistake + - dir: subdir to search + - filename: set this filename + - filesize: filesize for the file +*/ +#define MAX_RECUR 16 +static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth) +{ + /* file searching stuff */ + DIR *dir; + int file = 0; + struct dirent *de; + struct stat status; + char path[FILE_MAX]; + int size; + + printf("DIR %s\n", dirname); + + dir = opendir(dirname); + + if (dir==0) + return 0; + + if (*filesize == -1) + *filesize = 0; /* dir opened fine */ + + while ((de = readdir(dir)) != NULL) { + + if (strncmp(".", de->d_name, 2)==0 || strncmp("..", de->d_name, 3)==0) + continue; + + BLI_join_dirfile(path, dirname, de->d_name); + + if (stat(path, &status) != 0) + continue; /* cant stat, dont bother with this file, could print debug info here */ + + if (S_ISREG(status.st_mode)) { /* is file */ + if (strncmp(filename, de->d_name, FILE_MAX)==0) { /* name matches */ + /* open the file to read its size */ + file = open(path, O_BINARY|O_RDONLY); + if (file >=0 ) { + size = BLI_filesize(file); + if (size > *filesize) { /* find the biggest file */ + *filesize = size; + BLI_strncpy(filename_new, path, FILE_MAX); + } + close(file); + } + } + } else if (S_ISDIR(status.st_mode)) { /* is subdir */ + if (*recur_depth <= MAX_RECUR) { + (*recur_depth)++; + findFileRecursive(filename_new, path, filename, filesize, recur_depth); + (*recur_depth)--; + } + } + } + closedir(dir); + return 1; +} + +/* high level function - call from fileselector */ +void findMissingFiles(char *str) { + struct BPathIterator bpi; + + /* be sure there is low chance of the path being too short */ + char filepath_expanded[FILE_MAXDIR*2]; + char *filepath, *libpath; + int filesize, recur_depth; + + char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX], dummyname[FILE_MAX]; + + BLI_split_dirfile(str, dirname, dummyname); + + BLI_bpathIterator_init(&bpi); + + while (!BLI_bpathIterator_isDone(&bpi)) { + filepath = BLI_bpathIterator_getPath(&bpi); + libpath = BLI_bpathIterator_getLib(&bpi); + + if (libpath==NULL) { + + BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded ); + + if (!BLI_exists(filepath_expanded)) { + /* can the dir be opened? */ + filesize = -1; + recur_depth = 0; + BLI_split_dirfile(filepath, dummyname, filename); /* the file to find */ + + findFileRecursive(filename_new, dirname, filename, &filesize, &recur_depth); + if (filesize == -1) { /* could not open dir */ + printf("Could not open dir \"%s\"\n", dirname); + return; + } + + if (filesize > 0) { + + if (BLI_bpathIterator_getPathMaxLen( &bpi ) < strlen(filename_new)) { + printf("cannot set path \"%s\" too long!", filename_new); + } else { + /* copy the found path into the old one */ + if (G.relbase_valid) + BLI_makestringcode(G.sce, filename_new); + + strcpy( BLI_bpathIterator_getPath( &bpi ), filename_new ); + } + } + } + } + BLI_bpathIterator_step(&bpi); + } +} diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index bf4beacaa58..f3933507a7b 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -101,6 +101,7 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BLI_bpath.h" #include "BLO_writefile.h" #include "BSE_editipo.h" @@ -852,19 +853,6 @@ static void do_info_filemenu(void *arg, int event) case 25: BIF_screendump(1); break; - case 10: /* pack data */ - check_packAll(); - break; - case 11: /* unpack to current dir */ - unpackAll(PF_WRITE_LOCAL); - G.fileflags &= ~G_AUTOPACK; - break; - case 12: /* unpack data */ - if (buttons_do_unpack() != RET_CANCEL) { - /* Clear autopack bit only if user selected one of the unpack options */ - G.fileflags &= ~G_AUTOPACK; - } - break; case 13: exit_usiblender(); break; @@ -902,6 +890,7 @@ static void do_info_filemenu(void *arg, int event) U.flag ^= (USER_FILECOMPRESS); break; } + allqueue(REDRAWINFO, 0); } @@ -944,6 +933,81 @@ static uiBlock *info_openrecentmenu(void *arg_unused) return block; } +static void do_info_externalfiles(void *arg, int event) +{ + switch (event) { + + case 1: /* pack data */ + check_packAll(); + break; +#if 0 + case 2: /* unpack to current dir */ + unpackAll(PF_WRITE_LOCAL); + G.fileflags &= ~G_AUTOPACK; + break; +#endif + case 3: /* unpack data */ + if (buttons_do_unpack() != RET_CANCEL) { + /* Clear autopack bit only if user selected one of the unpack options */ + G.fileflags &= ~G_AUTOPACK; + } + break; + case 10: /* make all paths relative */ + { + int tot,changed,failed,linked; + char str[512]; + makeFilesRelative(&tot, &changed, &failed, &linked); + sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); + pupmenu(str); + } + break; + case 11: /* check images exist */ + { + /* Its really text but only care about the name */ + ID *btxt = (ID *)checkMissingFiles(); + + if (btxt) { + char str[128]; + sprintf(str, "Missing files listed in Text \"%s\"", btxt->name+2); + error(str); + } else { + okee("No external files missing"); + } + } + break; + case 12: /* search for referenced files that are not available */ + activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles); + break; + } + + allqueue(REDRAWINFO, 0); +} + +static uiBlock *info_externalfiles(void *arg_unused) +{ + uiBlock *block; + short yco = 20, menuwidth = 120; + + block= uiNewBlock(&curarea->uiblocks, "info_externalfiles", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_info_externalfiles, NULL); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into Blend", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, ""); +#if 0 + uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Removes all packed files from the project and saves them to the current directory"); +#endif + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack into Files...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, ""); + + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, ""); + + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block, 60); + return block; +} + static uiBlock *info_filemenu(void *arg_unused) { uiBlock *block; @@ -997,13 +1061,11 @@ static uiBlock *info_filemenu(void *arg_unused) uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Data", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, ""); -// uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "Removes all packed files from the project and saves them to the current directory"); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack Data...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, ""); - + + uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); uiBlockSetDirection(block, UI_DOWN); From 9b89abaa8b3689383a8c557981a482d9b1156165 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 20 Dec 2007 10:38:01 +0000 Subject: [PATCH 15/99] BLI_makestringcode dosnt need the first value to be a copy of G.sce since its a "const char" Removed own script release/scripts/image_find_paths.py since last commit replaced its functionality. --- release/scripts/image_find_paths.py | 167 ---------------------------- source/blender/src/editseq.c | 20 ++-- 2 files changed, 8 insertions(+), 179 deletions(-) delete mode 100644 release/scripts/image_find_paths.py diff --git a/release/scripts/image_find_paths.py b/release/scripts/image_find_paths.py deleted file mode 100644 index 266ecee9435..00000000000 --- a/release/scripts/image_find_paths.py +++ /dev/null @@ -1,167 +0,0 @@ -#!BPY - -""" -Name: 'Fix Broken Paths' -Blender: 242 -Group: 'Image' -Tooltip: 'Search for new image paths to make relative links to' -""" - -__author__ = "Campbell Barton AKA Ideasman" -__url__ = ["blenderartist.org"] - -__bpydoc__ = """\ -Find image target paths - -This script searches for images whos -file paths do not point to an existing image file, -all image paths are made relative where possible. -usefull when moving projects between computers, when absolute paths links are broken. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -from Blender import * - -try: - import os -except: - Draw.PupMenu('You need a full python install to use this script') - os= None - - -#==============================================# -# Strips the slashes from the back of a string # -#==============================================# -def stripPath(path): - return path.split('/')[-1].split('\\')[-1] - -# finds the file starting at the root. -def findImage(findRoot, imagePath): - newImageFile = None - - imageFile = imagePath.split('/')[-1].split('\\')[-1] - - # ROOT, DIRS, FILES - pathWalk = os.walk(findRoot) - pathList = [True] - - matchList = [] # Store a list of (match, size), choose the biggest. - while True: - try: - pathList = pathWalk.next() - except: - break - - for file in pathList[2]: - # FOUND A MATCH - if file.lower() == imageFile.lower(): - name = pathList[0] + sys.sep + file - try: - size = os.path.getsize(name) - except: - size = 0 - - if size: - print ' found:', name - matchList.append( (name, size) ) - - if matchList == []: - print 'no match for:', imageFile - return None - else: - # Sort by file size - matchList.sort(lambda A, B: cmp(B[1], A[1]) ) - - print 'using:', matchList[0][0] - # First item is the largest - return matchList[0][0] # 0 - first, 0 - pathname - - -# Makes the pathe relative to the blend file path. -def makeRelative(path, blendBasePath): - if path.startswith(blendBasePath): - path = path.replace(blendBasePath, '//') - path = path.replace('//\\', '//') - return path - -def find_images(findRoot): - print findRoot - - # findRoot = Draw.PupStrInput ('find in: ', '', 100) - - if findRoot == '': - Draw.PupMenu('No Directory Selected') - return - - # Account for // - findRoot = sys.expandpath(findRoot) - - # Strip filename - while findRoot[-1] != '/' and findRoot[-1] != '\\': - findRoot = findRoot[:-1] - - - if not findRoot.endswith(sys.sep): - findRoot += sys.sep - - - if findRoot != '/' and not sys.exists(findRoot[:-1]): - Draw.PupMenu('Directory Dosent Exist') - - blendBasePath = sys.expandpath('//') - - - Window.WaitCursor(1) - # ============ DIR DONE\ - images = Image.Get() - len_images = float(len(images)) - for idx, i in enumerate(images): - - progress = idx / len_images - Window.DrawProgressBar(progress, 'searching for images') - - # If files not there? - if not sys.exists(sys.expandpath(i.filename )): - newImageFile = findImage(findRoot, i.filename) - if newImageFile != None: - newImageFile= makeRelative(newImageFile, blendBasePath) - print 'newpath relink:', newImageFile - i.filename = newImageFile - i.reload() - else: - # Exists - newImageFile= makeRelative(i.filename, blendBasePath) - if newImageFile!=i.filename: - print 'newpath relative:', newImageFile - i.filename = newImageFile - - - Window.RedrawAll() - Window.DrawProgressBar(1.0, '') - Window.WaitCursor(0) - -if __name__ == '__main__' and os: - Window.FileSelector(find_images, 'SEARCH ROOT DIR', sys.expandpath('//')) - - diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index 75ac58285a2..bc453dd5a2e 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -955,7 +955,7 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int Strip *strip; StripElem *se; int totsel, a; - char name[160], rel[160]; + char name[160]; /* are there selected files? */ totsel= 0; @@ -987,8 +987,7 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int if(sfile->flag & FILE_STRINGCODE) { strcpy(name, sfile->dir); - strcpy(rel, G.sce); - BLI_makestringcode(rel, name); + BLI_makestringcode(G.sce, name); } else { strcpy(name, sfile->dir); } @@ -1028,7 +1027,7 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra, Strip *strip; StripElem *se; int totframe; - char name[160], rel[160]; + char name[160]; char str[FILE_MAXDIR+FILE_MAXFILE]; totframe= 0; @@ -1060,8 +1059,7 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra, if(sfile->flag & FILE_STRINGCODE) { strcpy(name, sfile->dir); - strcpy(rel, G.sce); - BLI_makestringcode(rel, name); + BLI_makestringcode(G.sce, name); } else { strcpy(name, sfile->dir); } @@ -1123,7 +1121,7 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile, Strip *strip; StripElem *se; double totframe; - char name[160], rel[160]; + char name[160]; char str[256]; totframe= 0.0; @@ -1157,8 +1155,7 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile, if(sfile->flag & FILE_STRINGCODE) { strcpy(name, sfile->dir); - strcpy(rel, G.sce); - BLI_makestringcode(rel, name); + BLI_makestringcode(G.sce, name); } else { strcpy(name, sfile->dir); } @@ -1187,7 +1184,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra, Strip *strip; StripElem *se; int totframe; - char name[160], rel[160]; + char name[160]; char str[FILE_MAXDIR+FILE_MAXFILE]; totframe= 0; @@ -1218,8 +1215,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra, if(sfile->flag & FILE_STRINGCODE) { strcpy(name, sfile->dir); - strcpy(rel, G.sce); - BLI_makestringcode(rel, name); + BLI_makestringcode(G.sce, name); } else { strcpy(name, sfile->dir); } From a637aca44ab6b19e054c605ff412be59d7828563 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 20 Dec 2007 10:52:56 +0000 Subject: [PATCH 16/99] make relative paths wasnt working, also disallowed it when the blend file isnt saved --- source/blender/blenlib/intern/bpath.c | 6 +++--- source/blender/src/header_info.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 598b5720b65..4e394bb7fae 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -345,7 +345,7 @@ void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { filepath = BLI_bpathIterator_getPath(&bpi); libpath = BLI_bpathIterator_getLib(&bpi); - if(strncmp(filepath, "//", 2)==0) { + if(strncmp(filepath, "//", 2)) { if (libpath) { /* cant make relative if we are kibrary - TODO, LOG THIS */ (*linked)++; } else { /* local data, use the blend files path */ @@ -356,10 +356,10 @@ void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { } else { /* safe to to check the length */ if(strncmp(filepath_relative, "//", 2)==0) { - (*failed)++; - } else { strcpy(filepath, filepath_relative); (*changed)++; + } else { + (*failed)++; } } } diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index f3933507a7b..fd7495dbbbe 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -953,12 +953,14 @@ static void do_info_externalfiles(void *arg, int event) } break; case 10: /* make all paths relative */ - { + if (G.relbase_valid) { int tot,changed,failed,linked; char str[512]; makeFilesRelative(&tot, &changed, &failed, &linked); sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); pupmenu(str); + } else { + pupmenu("Can't set relative paths with an unsaved blend file"); } break; case 11: /* check images exist */ From 846e4027ce65f62654afcf23ed18365d8e501c1e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 20 Dec 2007 12:37:15 +0000 Subject: [PATCH 17/99] hopefully fix compiling on win32 --- source/blender/blenlib/intern/bpath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 4e394bb7fae..2c1ebd59a55 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -53,19 +53,20 @@ /* path/file handeling stuff */ #ifndef WIN32 #include + #include #else #include "BLI_winstuff.h" + #include #endif #include #include -#include #include #include #include #include -#include + #define FILE_MAX 240 From 2e48a4af57759e61a1afd89edb19a4dc92ced728 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 20 Dec 2007 16:33:45 +0000 Subject: [PATCH 18/99] change default solaris gcc args, use -m64 for 64bit arch, use -O2 rather then -O1 --- source/nan_compile.mk | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/source/nan_compile.mk b/source/nan_compile.mk index d5bf04c4b33..c723ff4bfc6 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -181,18 +181,25 @@ ifeq ($(OS),solaris) CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing # CFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned" # CCFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned" - REL_CFLAGS += -O1 - REL_CCFLAGS += -O1 + + ifeq ($(findstring 64,$(CPU)), 64) + CFLAGS += -m64 + CCFLAGS += -m64 + endif + + REL_CFLAGS += -O2 + REL_CCFLAGS += -O2 + NAN_DEPEND = true - #ifeq ($(CPU),sparc) - ifeq ($(CPU),$(findstring $(CPU), "sparc")) - OPENGL_HEADERS = /usr/openwin/share/include - CPPFLAGS += -DSUN_OGL_NO_VERTEX_MACROS - JAVA_HEADERS = /usr/java/include - JAVA_SYSTEM_HEADERS = /usr/java/include/solaris - else - OPENGL_HEADERS = $(LCGDIR)/mesa/include - endif +# ifeq ($(CPU),sparc) + ifeq ($(findstring sparc,$(CPU)), sparc) + OPENGL_HEADERS = /usr/openwin/share/include + CPPFLAGS += -DSUN_OGL_NO_VERTEX_MACROS + JAVA_HEADERS = /usr/java/include + JAVA_SYSTEM_HEADERS = /usr/java/include/solaris + else + OPENGL_HEADERS = $(LCGDIR)/mesa/include + endif AR = ar ARFLAGS = ruv ARFLAGSQUIET = ru From 0f2b2e3c60173e85e137df71392d867576e65ac1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 20 Dec 2007 16:35:27 +0000 Subject: [PATCH 19/99] Strand Render Simplification ============================ - Strand render now has options to remove child strands as the object's faces becomes smaller, in the Simplification particle panel. - "Reference Size" is the approximate size of the object on screen, after which simplification starts. - "Rate" is how fast strands are removed. - "Transition" is the percentage of strands being faded out as they are removed. - Another "Viewport" option removes strands on faces that are outside of the viewport. "Rate" again controls how fast these are removed. - Strand render in Blender Units now has an adjustable minimum width. Below this minimum width, strands start fading out instead of getting smaller. --- source/blender/blenkernel/BKE_particle.h | 10 +- source/blender/blenkernel/intern/particle.c | 308 +++++++++++++++++- .../blenkernel/intern/particle_system.c | 103 +++--- source/blender/blenloader/intern/readfile.c | 16 +- source/blender/makesdna/DNA_material_types.h | 1 + source/blender/makesdna/DNA_particle_types.h | 9 + .../render/intern/include/render_types.h | 2 +- .../render/intern/include/renderdatabase.h | 2 + source/blender/render/intern/include/strand.h | 3 + .../render/intern/source/convertblender.c | 45 ++- .../render/intern/source/renderdatabase.c | 18 + source/blender/render/intern/source/strand.c | 49 ++- source/blender/src/buttons_object.c | 44 ++- source/blender/src/buttons_shading.c | 34 +- 14 files changed, 545 insertions(+), 99 deletions(-) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 1c69fe613c7..a1ac97406e1 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -112,8 +112,8 @@ typedef struct ParticleSeam{ typedef struct ParticleCacheKey{ float co[3]; float vel[3]; - float rot[4]; float col[3]; + float rot[4]; int steps; } ParticleCacheKey; @@ -165,7 +165,7 @@ typedef struct ParticleThreadContext { float *jit, *jitoff, *weight; float maxweight; - int *index, jitlevel; + int *index, *skip, jitlevel; int from, cfrom, distr; @@ -214,8 +214,10 @@ void free_hair(struct ParticleSystem *psys); void free_keyed_keys(struct ParticleSystem *psys); void psys_free(struct Object * ob, struct ParticleSystem * psys); -void psys_particles_to_render_backup(struct Object *ob, struct ParticleSystem *psys); -void psys_render_backup_to_particles(struct Object *ob, struct ParticleSystem *psys); +void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy); +void psys_render_restore(struct Object *ob, struct ParticleSystem *psys); +int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot); +int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params); void clear_particles_from_cache(struct Object *ob, struct ParticleSystem *psys, int cfra); //void psys_remove_from_particle_list(struct Object *ob, short nbr, struct ParticleSystem *psys); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 85ac809bf70..32f1795747a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -295,7 +295,6 @@ void free_keyed_keys(ParticleSystem *psys) } void free_child_path_cache(ParticleSystem *psys) { - if(psys->childcache){ if(psys->childcache[0]) MEM_freeN(psys->childcache[0]); @@ -363,28 +362,98 @@ void psys_free(Object *ob, ParticleSystem * psys) } } -/* these two functions move away particle data and bring it back after +/* these functions move away particle data and bring it back after * rendering, to make different render settings possible without * removing the previous data. this should be solved properly once */ -typedef struct ParticleRenderDataup { +typedef struct ParticleRenderElem { + int curchild, totchild; + float lambda, t, scalemin, scalemax; +} ParticleRenderElem; + +typedef struct ParticleRenderData { ChildParticle *child; ParticleCacheKey **pathcache; ParticleCacheKey **childcache; int totchild, totcached, totchildcache; DerivedMesh *dm; int totdmvert, totdmedge, totdmface; -} ParticleRenderDataup; -void psys_particles_to_render_backup(Object *ob, ParticleSystem *psys) + float mat[4][4]; + float viewmat[4][4], winmat[4][4]; + int winx, winy; + + int dosimplify; + ParticleRenderElem *elems; + int *origindex; +} ParticleRenderData; + +static float psys_render_viewport_falloff(double rate, float dist, float width) { - ParticleRenderDataup *data; + return pow(rate, dist/width); +} + +static float psys_render_projected_area(ParticleSystem *psys, float *center, float area, double vprate, float *viewport) +{ + ParticleRenderData *data= psys->renderdata; + float co[3], view[3], ortho1[3], ortho2[2], w, dx, dy, radius; + + /* transform to view space */ + VECCOPY(co, center); + co[3]= 1.0f; + Mat4MulVec4fl(data->viewmat, co); + + /* compute two vectors orthogonal to view vector */ + VECCOPY(view, co); + Normalize(view); + VecOrthoBasisf(view, ortho1, ortho2); + + /* compute on screen minification */ + w= co[2]*data->winmat[2][3] + data->winmat[3][3]; + dx= data->winx*ortho2[0]*data->winmat[0][0]; + dy= data->winy*ortho2[1]*data->winmat[1][1]; + w= sqrt(dx*dx + dy*dy)/w; + + /* w squared because we are working with area */ + area= area*w*w; + + /* viewport of the screen test */ + + /* project point on screen */ + Mat4MulVec4fl(data->winmat, co); + if(co[3] != 0.0f) { + co[0]= 0.5f*data->winx*(1.0f + co[0]/co[3]); + co[1]= 0.5f*data->winy*(1.0f + co[1]/co[3]); + } + + /* screen space radius */ + radius= sqrt(area/M_PI); + + /* make smaller using fallof once over screen edge */ + *viewport= 1.0f; + + if(co[0]+radius < 0.0f) + *viewport *= psys_render_viewport_falloff(vprate, -(co[0]+radius), data->winx); + else if(co[0]-radius > data->winx) + *viewport *= psys_render_viewport_falloff(vprate, (co[0]-radius) - data->winx, data->winx); + + if(co[1]+radius < 0.0f) + *viewport *= psys_render_viewport_falloff(vprate, -(co[1]+radius), data->winy); + else if(co[1]-radius > data->winy) + *viewport *= psys_render_viewport_falloff(vprate, (co[1]-radius) - data->winy, data->winy); + + return area; +} + +void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy) +{ + ParticleRenderData*data; ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); if(!G.rendering) return; - data= MEM_callocN(sizeof(ParticleRenderDataup), "ParticleRenderDataup"); + data= MEM_callocN(sizeof(ParticleRenderData), "ParticleRenderData"); data->child= psys->child; data->totchild= psys->totchild; @@ -404,17 +473,26 @@ void psys_particles_to_render_backup(Object *ob, ParticleSystem *psys) psys->childcache= NULL; psys->totchild= psys->totcached= psys->totchildcache= 0; + Mat4CpyMat4(data->winmat, winmat); + Mat4MulMat4(data->viewmat, ob->obmat, viewmat); + Mat4MulMat4(data->mat, data->viewmat, winmat); + data->winx= winx; + data->winy= winy; + psys->renderdata= data; } -void psys_render_backup_to_particles(Object *ob, ParticleSystem *psys) +void psys_render_restore(Object *ob, ParticleSystem *psys) { - ParticleRenderDataup *data; + ParticleRenderData*data; ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); data= psys->renderdata; if(!data) return; + + if(data->elems) + MEM_freeN(data->elems); if(psmd->dm) { psmd->dm->needsFree= 1; @@ -428,7 +506,7 @@ void psys_render_backup_to_particles(Object *ob, ParticleSystem *psys) psys->child= 0; psys->totchild= 0; } - + psys->child= data->child; psys->totchild= data->totchild; psys->pathcache= data->pathcache; @@ -449,6 +527,211 @@ void psys_render_backup_to_particles(Object *ob, ParticleSystem *psys) psys->renderdata= NULL; } +int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) +{ + DerivedMesh *dm= ctx->dm; + Mesh *me= (Mesh*)(ctx->ob->data); + MFace *mf, *mface; + MVert *mvert; + ParticleRenderData *data; + ParticleRenderElem *elems, *elem; + ParticleSettings *part= ctx->psys->part; + float *facearea, (*facecenter)[3], size[3], fac, powrate; + float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport; + double vprate; + int *origindex, *facetotvert; + int a, b, totorigface, totface, newtot, skipped; + + if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) + return tot; + if(!ctx->psys->renderdata || !(part->simplify_flag & PART_SIMPLIFY_ENABLE)) + return tot; + + mvert= dm->getVertArray(dm); + mface= dm->getFaceArray(dm); + origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX); + totface= dm->getNumFaces(dm); + totorigface= me->totface; + + if(totface == 0 || totorigface == 0 || origindex == NULL) + return tot; + + facearea= MEM_callocN(sizeof(float)*totorigface, "SimplifyFaceArea"); + facecenter= MEM_callocN(sizeof(float[3])*totorigface, "SimplifyFaceCenter"); + facetotvert= MEM_callocN(sizeof(int)*totorigface, "SimplifyFaceArea"); + elems= MEM_callocN(sizeof(ParticleRenderElem)*totorigface, "SimplifyFaceElem"); + + data= ctx->psys->renderdata; + data->dosimplify= 1; + data->elems= elems; + data->origindex= origindex; + + /* compute number of children per original face */ + for(a=0; aindex[a]]; + if(b != -1) + elems[b].totchild++; + } + + /* compute areas and centers of original faces */ + for(mf=mface, a=0; av1].co); + VECCOPY(co2, mvert[mf->v2].co); + VECCOPY(co3, mvert[mf->v3].co); + + VECADD(facecenter[b], facecenter[b], co1); + VECADD(facecenter[b], facecenter[b], co2); + VECADD(facecenter[b], facecenter[b], co3); + + if(mf->v4) { + VECCOPY(co4, mvert[mf->v4].co); + VECADD(facecenter[b], facecenter[b], co4); + facearea[b] += AreaQ3Dfl(co1, co2, co3, co4); + facetotvert[b] += 4; + } + else { + facearea[b] += AreaT3Dfl(co1, co2, co3); + facetotvert[b] += 3; + } + } + } + + for(a=0; a 0) + VecMulf(facecenter[a], 1.0f/facetotvert[a]); + + /* for conversion from BU area / pixel area to reference screen size */ + mesh_get_texspace(me, 0, 0, size); + fac= ((size[0] + size[1] + size[2])/3.0f)/part->simplify_refsize; + fac= fac*fac; + + powrate= log(0.5f)/log(part->simplify_rate*0.5f); + if(part->simplify_flag & PART_SIMPLIFY_VIEWPORT) + vprate= pow(1.0 - part->simplify_viewport, 5.0); + else + vprate= 1.0; + + /* set simplification parameters per original face */ + for(a=0, elem=elems; apsys, facecenter[a], facearea[a], vprate, &viewport); + arearatio= fac*area/facearea[a]; + + if(arearatio < 1.0f || viewport < 1.0f) { + /* lambda is percentage of elements to keep */ + lambda= (arearatio < 1.0f)? pow(arearatio, powrate): 1.0f; + lambda *= viewport; + + /* compute transition region */ + t= part->simplify_transition; + elem->t= (lambda-t < 0.0f)? lambda: (lambda+t > 1.0f)? 1.0f-lambda: t; + + /* scale at end and beginning of the transition region */ + elem->scalemax= (lambda+t < 1.0f)? 1.0f/lambda: 1.0f/(1.0f - elem->t*elem->t/t); + elem->scalemin= (lambda+t < 1.0f)? 0.0f: elem->scalemax*(1.0f-elem->t/t); + + /* extend lambda to include transition */ + lambda= lambda + elem->t; + if(lambda > 1.0f) + lambda= 1.0f; + } + else { + lambda= arearatio; + + elem->scalemax= 1.0f; //sqrt(lambda); + elem->scalemin= 1.0f; //sqrt(lambda); + } + + elem->lambda= lambda; + elem->scalemin= sqrt(elem->scalemin); + elem->scalemax= sqrt(elem->scalemax); + elem->curchild= 0; + } + + MEM_freeN(facearea); + MEM_freeN(facecenter); + MEM_freeN(facetotvert); + + /* move indices and set random number skipping */ + ctx->skip= MEM_callocN(sizeof(int)*tot, "SimplificationSkip"); + + skipped= 0; + for(a=0, newtot=0; aindex[a]]; + if(b != -1) { + if(elems[b].curchild++ < ceil(elems[b].lambda*elems[b].totchild)) { + ctx->index[newtot]= ctx->index[a]; + ctx->skip[newtot]= skipped; + skipped= 0; + newtot++; + } + else skipped++; + } + else skipped++; + } + + for(a=0, elem=elems; acurchild= 0; + + return newtot; +} + +int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float *params) +{ + ParticleRenderData *data; + ParticleRenderElem *elem; + float x, w, scale, alpha, lambda, t, scalemin, scalemax; + int b; + + if(!(psys->renderdata && (psys->part->simplify_flag & PART_SIMPLIFY_ENABLE))) + return 0; + + data= psys->renderdata; + if(!data->dosimplify) + return 0; + + b= data->origindex[cpa->num]; + if(b == -1) + return 0; + + elem= &data->elems[b]; + + lambda= elem->lambda; + t= elem->t; + scalemin= elem->scalemin; + scalemax= elem->scalemax; + + if(lambda >= 1.0f) { + scale= scalemin; + alpha= 1.0f; + } + else { + x= (elem->curchild+0.5f)/elem->totchild; + if(x < lambda-t) { + scale= scalemax; + alpha= 1.0f; + } + else if(x >= lambda+t) { + scale= scalemin; + alpha= 0.0f; + } + else { + w= (lambda+t - x)/(2.0f*t); + scale= scalemin + (scalemax - scalemin)*w; + alpha= w; + } + } + + params[0]= scale; + params[1]= alpha; + + elem->curchild++; + + return 1; +} + /************************************************/ /* Interpolated Particles */ /************************************************/ @@ -2550,6 +2833,11 @@ static void default_particle_settings(ParticleSettings *part) } part->ipo = NULL; + + part->simplify_refsize= 1920; + part->simplify_rate= 1.0f; + part->simplify_transition= 0.1f; + part->simplify_viewport= 0.8; } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index af1db36b648..a8ccd12874e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -105,13 +105,13 @@ static int get_current_display_percentage(ParticleSystem *psys) return psys->part->disp; } -static void alloc_particles(ParticleSystem *psys, int new_totpart) +static void alloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) { ParticleData *newpars = 0, *pa; - int i, child_nbr, totpart, totsaved = 0; + int i, totpart, totsaved = 0; - if(new_totpart<0){ - if(psys->part->distr==PART_DISTR_GRID){ + if(new_totpart<0) { + if(psys->part->distr==PART_DISTR_GRID) { totpart= psys->part->grid_res; totpart*=totpart*totpart; } @@ -123,7 +123,7 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart) if(totpart) newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles"); - if(psys->particles){ + if(psys->particles) { totsaved=MIN2(psys->totpart,totpart); /*save old pars*/ if(totsaved) @@ -136,16 +136,7 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart) } psys->particles=newpars; - child_nbr= (psys->renderdata)? psys->part->ren_child_nbr: psys->part->child_nbr; - if(child_nbr && psys->part->childtype){ - if(psys->child) - MEM_freeN(psys->child); - psys->child = NULL; - if(totpart) - psys->child= MEM_callocN(totpart*child_nbr*sizeof(ChildParticle), "child_particles"); - psys->totchild=totpart*child_nbr; - } - else if(psys->child){ + if(psys->child) { MEM_freeN(psys->child); psys->child=0; psys->totchild=0; @@ -154,6 +145,32 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart) psys->totpart=totpart; } +static int get_alloc_child_particles_tot(ParticleSystem *psys) +{ + int child_nbr; + + if(!psys->part->childtype) + return 0; + + child_nbr= (psys->renderdata)? psys->part->ren_child_nbr: psys->part->child_nbr; + return psys->totpart*child_nbr; +} + +static void alloc_child_particles(ParticleSystem *psys, int tot) +{ + if(psys->child){ + MEM_freeN(psys->child); + psys->child=0; + psys->totchild=0; + } + + if(psys->part->childtype) { + psys->totchild= tot; + if(psys->totchild) + psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles"); + } +} + /* only run this if from == PART_FROM_FACE */ void psys_calc_dmfaces(Object *ob, DerivedMesh *dm, ParticleSystem *psys) { @@ -607,7 +624,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C } mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE); - + //switch(distr){ // case PART_DISTR_JIT: // i=index[p]; @@ -741,12 +758,16 @@ void *exec_distribution(void *data) if(thread->ctx->from == PART_FROM_CHILD) { totpart= psys->totchild; - cpa= psys->child + thread->num; + cpa= psys->child; - rng_skip(thread->rng, 5*thread->num); - for(p=thread->num; ptot, cpa+=thread->tot) { - psys_thread_distribute_particle(thread, NULL, cpa, p); - rng_skip(thread->rng, 5*(thread->tot-1)); + for(p=0; pctx->skip) /* simplification skip */ + rng_skip(thread->rng, 5*thread->ctx->skip[p]); + + if((p+thread->num) % thread->tot == 0) + psys_thread_distribute_particle(thread, NULL, cpa, p); + else /* thread skip */ + rng_skip(thread->rng, 5); } } else { @@ -757,7 +778,7 @@ void *exec_distribution(void *data) } return 0; -} +} /* creates a distribution of coordinates on a DerivedMesh */ /* */ @@ -813,7 +834,6 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm if(from==PART_FROM_CHILD){ distr=PART_DISTR_RAND; - cpa=psys->child; if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ dm= finaldm; children=1; @@ -828,7 +848,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm BLI_kdtree_balance(tree); - totpart=psys->totchild; + totpart=get_alloc_child_particles_tot(psys); cfrom=from=PART_FROM_FACE; if(part->flag&PART_CHILD_SEAMS){ @@ -879,6 +899,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm /* no need to figure out distribution */ int child_nbr= (psys->renderdata)? part->ren_child_nbr: part->child_nbr; + alloc_child_particles(psys, 1.0f); + cpa=psys->child; for(i=0; itotpart; p++,cpa++){ float length=2.0; @@ -1100,7 +1122,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm sum[0]= 0.0f; for(i=0;iflag&PART_TRAND){ float pos; @@ -1156,9 +1178,6 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm } /* 5. */ - if(children) - from=PART_FROM_CHILD; - ctx->tree= tree; ctx->seams= seams; ctx->totseam= totseam; @@ -1169,17 +1188,21 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm ctx->jitoff= jitoff; ctx->weight= weight; ctx->maxweight= maxweight; - ctx->from= from; + ctx->from= (children)? PART_FROM_CHILD: from; ctx->cfrom= cfrom; ctx->distr= distr; ctx->dm= dm; ctx->tpars= tpars; - seed= 31415926 + ctx->psys->seed; + if(children) { + totpart= psys_render_simplify_distribution(ctx, totpart); + alloc_child_particles(psys, totpart); + } - if(from!=PART_FROM_CHILD || psys->totchild < 10000) + if(!children || psys->totchild < 10000) totthread= 1; + seed= 31415926 + ctx->psys->seed; for(i=0; ijitoff) MEM_freeN(ctx->jitoff); if(ctx->weight) MEM_freeN(ctx->weight); if(ctx->index) MEM_freeN(ctx->index); + if(ctx->skip) MEM_freeN(ctx->skip); if(ctx->seams) MEM_freeN(ctx->seams); //if(ctx->vertpart) MEM_freeN(ctx->vertpart); BLI_kdtree_free(ctx->tree); @@ -4188,13 +4212,16 @@ static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd, if(distr){ if(alloc) - alloc_particles(psys,psys->totpart); + alloc_particles(ob,psys,psys->totpart); - if(psys->totchild && part->childtype){ - distribute_particles(ob,psys,PART_FROM_CHILD); + if(get_alloc_child_particles_tot(psys)) { + /* don't generate children while computing the hair keys */ + if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { + distribute_particles(ob,psys,PART_FROM_CHILD); - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) - psys_find_parents(ob,psmd,psys); + if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) + psys_find_parents(ob,psmd,psys); + } } } @@ -4413,11 +4440,11 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier if(init) { if(distr) { if(alloc) - alloc_particles(psys, totpart); + alloc_particles(ob, psys, totpart); distribute_particles(ob, psys, part->from); - if(psys->totchild && part->childtype) + if(get_alloc_child_particles_tot(psys)) distribute_particles(ob, psys, PART_FROM_CHILD); } initialize_all_particles(ob, psys, psmd); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index cf71d9ab41e..8bbcc7016c1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6826,7 +6826,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } for(ma=main->mat.first; ma; ma= ma->id.next) { - if (ma->samp_gloss_mir == 0) { + if(ma->samp_gloss_mir == 0) { ma->gloss_mir = ma->gloss_tra= 1.0; ma->aniso_gloss_mir = 1.0; ma->samp_gloss_mir = ma->samp_gloss_tra= 18; @@ -6834,11 +6834,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ma->dist_mir = 0.0; ma->fadeto_mir = MA_RAYMIR_FADETOSKY; } + + if(ma->strand_min == 0.0f) + ma->strand_min= 1.0f; } - for(part=main->particle.first; part; part=part->id.next) + for(part=main->particle.first; part; part=part->id.next) { if(part->ren_child_nbr==0) part->ren_child_nbr= part->child_nbr; + + if(part->simplify_refsize==0) { + part->simplify_refsize= 1920; + part->simplify_rate= 1.0f; + part->simplify_transition= 0.1f; + part->simplify_viewport= 0.8f; + } + } + if (main->versionfile < 245 || main->subversionfile < 12) { /* initialize skeleton generation toolsettings */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 22585e59c7b..f0b06585f27 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -85,6 +85,7 @@ typedef struct Material { short flarec, starc, linec, ringc; float hasize, flaresize, subsize, flareboost; float strand_sta, strand_end, strand_ease, strand_surfnor; + float strand_min, strand_pad; char strand_uvname[32]; float sbias; /* shadow bias */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index a00d7d484d9..942c837df97 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -121,6 +121,11 @@ typedef struct ParticleSettings { short bb_align, bb_uv_split, bb_anim, bb_split_offset; float bb_tilt, bb_rand_tilt, bb_offset[2]; + /* simplification */ + short simplify_flag, simplify_refsize; + float simplify_rate, simplify_transition; + float simplify_viewport; + /* general values */ float sta, end, lifetime, randlife; float timetweak, jitfac, keyed_time; @@ -307,6 +312,10 @@ typedef struct ParticleSystem{ #define PART_DRAW_WHOLE_GR (1<<14) #define PART_DRAW_REN_STRAND (1<<15) +/* part->simplify_flag */ +#define PART_SIMPLIFY_ENABLE 1 +#define PART_SIMPLIFY_VIEWPORT 2 + /* part->bb_align */ #define PART_BB_X 0 #define PART_BB_Y 1 diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 4a731878ffb..7fbbd0f5abc 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -343,7 +343,7 @@ typedef struct StrandBuffer { unsigned int lay; int overrideuv; int flag, maxdepth; - float adaptcos; + float adaptcos, minwidth; float winmat[4][4]; int winx, winy; diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 0346f2d6413..c919a54008e 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -69,6 +69,7 @@ typedef struct StrandTableNode { struct StrandRen *strand; float *winspeed; float *surfnor; + float *simplify; struct MCol *mcol; float *uv; int totuv, totmcol; @@ -112,6 +113,7 @@ int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, stru float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify); float *RE_strandren_get_uv(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify); struct MCol *RE_strandren_get_mcol(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify); +float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify); float *RE_strandren_get_winspeed(struct ObjectInstanceRen *obi, struct StrandRen *strand, int verify); struct VertRen *RE_vertren_copy(struct ObjectRen *obr, struct VertRen *ver); diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h index 7f37317d4d5..34a147c1933 100644 --- a/source/blender/render/intern/include/strand.h +++ b/source/blender/render/intern/include/strand.h @@ -68,6 +68,9 @@ typedef struct StrandPoint { /* screen space */ float hoco[4]; float x, y; + + /* simplification */ + float alpha; } StrandPoint; typedef struct StrandSegment { diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index de3bd6079a4..eb5bb3f2f71 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -983,7 +983,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo { static VertRen *v1= NULL, *v2= NULL; VlakRen *vlr; - float nor[3], cross[3], w, dx, dy, width; + float nor[3], cross[3], crosslen, w, dx, dy, width; static float anor[3], avec[3]; int flag, i; static int second=0; @@ -992,14 +992,11 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo Normalize(nor); // nor needed as tangent Crossf(cross, vec, nor); - if(ma->mode&MA_STR_B_UNITS) - Normalize(cross); - /* turn cross in pixelsize */ w= vec[2]*re->winmat[2][3] + re->winmat[3][3]; - dx= re->winx*cross[0]*re->winmat[0][0]/w; - dy= re->winy*cross[1]*re->winmat[1][1]/w; - w= sqrt(dx*dx + dy*dy); + dx= re->winx*cross[0]*re->winmat[0][0]; + dy= re->winy*cross[1]*re->winmat[1][1]; + w= sqrt(dx*dx + dy*dy)/w; if(w!=0.0f) { float fac; @@ -1013,12 +1010,16 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end); - /* use actual Blender units for strand width and fall back to min 1px */ + /* use actual Blender units for strand width and fall back to minimum width */ if(ma->mode & MA_STR_B_UNITS){ - if(width < 1.0f/w) - width= 1.0f/w; + crosslen= VecLength(cross); + w= 2.0f*crosslen*ma->strand_min/w; + + if(width < w) + width= w; + /*cross is the radius of the strand so we want it to be half of full width */ - VecMulf(cross,0.5); + VecMulf(cross,0.5/crosslen); } else width/=w; @@ -1496,7 +1497,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f; float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0); float loc_tex[3], size_tex[3], adapt_angle=0.0, adapt_pix=0.0, random; - int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1; + float simplify[2]; + int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0; int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild; int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}; char **uv_name=0; @@ -1639,9 +1641,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem Mat4CpyMat4(strandbuf->winmat, re->winmat); strandbuf->winx= re->winx; strandbuf->winy= re->winy; - strandbuf->maxdepth= 2; /* TODO */ + strandbuf->maxdepth= 2; strandbuf->adaptcos= cos((float)part->adapt_angle*(float)(M_PI/180.0)); strandbuf->overrideuv= override_uv; + strandbuf->minwidth= ma->strand_min; if(part->flag & PART_HAIR_BSPLINE) strandbuf->flag |= R_STRAND_BSPLINE; @@ -1720,7 +1723,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue; } - else{ + else { ChildParticle *cpa= psys->child+a-totpart; pa_time=psys_get_child_time(psys, cpa, cfra); @@ -1778,6 +1781,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } } + dosimplify= psys_render_simplify_params(psys, cpa, simplify); + if(path_nbr) { cache = psys->childcache[a-totpart]; max_k = (int)cache->steps; @@ -1805,6 +1810,12 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem strand->vert= svert; VECCOPY(strand->orco, orco); + if(dosimplify) { + float *ssimplify= RE_strandren_get_simplify(obr, strand, 1); + ssimplify[0]= simplify[0]; + ssimplify[1]= simplify[1]; + } + if(surfnor) { float *snor= RE_strandren_get_surfnor(obr, strand, 1); VECCOPY(snor, surfnor); @@ -3886,7 +3897,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in show_emitter= 0; for(psys=ob->particlesystem.first; psys; psys=psys->next) { show_emitter += psys->part->draw & PART_DRAW_EMITTER; - psys_particles_to_render_backup(ob, psys); + psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy); } /* if no psys has "show emitter" selected don't render emitter */ @@ -3910,7 +3921,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { obr= RE_addRenderObject(re, ob, par, index, psysindex); init_render_object_data(re, obr, only_verts); - psys_render_backup_to_particles(ob, psys); + psys_render_restore(ob, psys); /* only add instance for objects that have not been used for dupli */ if(!(ob->transflag & OB_RENDER_DUPLI)) @@ -4666,7 +4677,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce) } else { /* check if both have same amounts of vertices */ if(obi->totvector!=oldobi->totvector) { - printf("Warning: object %s has different amount of vertices on other frame\n", obi->ob->id.name+2); + printf("Warning: object %s has different amount of vertices or strands on other frame\n", obi->ob->id.name+2); continue; } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 3906b1fc001..79c87252fc2 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -104,6 +104,7 @@ #define RE_MCOL_ELEMS 4 #define RE_UV_ELEMS 2 #define RE_SURFNOR_ELEMS 3 +#define RE_SIMPLIFY_ELEMS 2 float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify) { @@ -590,6 +591,21 @@ MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **nam return node->mcol + index*RE_MCOL_ELEMS; } +float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify) +{ + float *simplify; + int nr= strand->index>>8; + + simplify= obr->strandnodes[nr].simplify; + if(simplify==NULL) { + if(verify) + simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify table"); + else + return NULL; + } + return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS; +} + /* winspeed is exception, it is stored per instance */ float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify) { @@ -743,6 +759,8 @@ void free_renderdata_strandnodes(StrandTableNode *strandnodes) MEM_freeN(strandnodes[a].winspeed); if(strandnodes[a].surfnor) MEM_freeN(strandnodes[a].surfnor); + if(strandnodes[a].simplify) + MEM_freeN(strandnodes[a].simplify); } MEM_freeN(strandnodes); diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 42c6d559f65..4f0e9764a43 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -321,7 +321,8 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) { Material *ma; StrandBuffer *strandbuf; - float p[4][3], data[4], cross[3], w, dx, dy, t; + float *simplify; + float p[4][3], data[4], cross[3], crosslen, w, dx, dy, t; int type; strandbuf= sseg->buffer; @@ -378,25 +379,34 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) Normalize(spoint->nor); spoint->width= strand_eval_width(ma, spoint->strandco); + + /* simplification */ + simplify= RE_strandren_get_simplify(strandbuf->obr, sseg->strand, 0); + spoint->alpha= (simplify)? simplify[1]: 1.0f; /* outer points */ Crossf(cross, spoint->co, spoint->tan); - if(strandbuf->flag & R_STRAND_B_UNITS) - Normalize(cross); - w= spoint->co[2]*strandbuf->winmat[2][3] + strandbuf->winmat[3][3]; - dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]/w; - dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]/w; - w= sqrt(dx*dx + dy*dy); + dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]; + dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]; + w= sqrt(dx*dx + dy*dy)/w; if(w > 0.0f) { if(strandbuf->flag & R_STRAND_B_UNITS) { - w= 1.0f/w; + crosslen= VecLength(cross); + w= 2.0f*crosslen*strandbuf->minwidth/w; - if(spoint->width < w) + if(spoint->width < w) { + spoint->alpha= spoint->width/w; spoint->width= w; - VecMulf(cross, spoint->width*0.5f); + } + + if(simplify) + /* squared because we only change width, not length */ + spoint->width *= simplify[0]*simplify[0]; + + VecMulf(cross, spoint->width*0.5f/crosslen); } else VecMulf(cross, spoint->width/w); @@ -528,7 +538,7 @@ static void strand_project_point(float winmat[][4], float winx, float winy, Stra } #include "BLI_rand.h" -void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint); +static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint); static void strand_shade_get(StrandPart *spart, int lookup, ShadeSample *ssamp, StrandPoint *spoint, StrandVert *svert, StrandSegment *sseg) { @@ -653,7 +663,7 @@ static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, floa return clipflag; } -void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint) +static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint) { ShadeInput *shi= ssamp->shi; ShadeResult *shr= ssamp->shr; @@ -685,6 +695,21 @@ void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, Str shade_samples_do_AO(ssamp); shade_input_do_shade(shi, shr); + /* apply simplification */ + if(spoint->alpha < 1.0f) { + shr->combined[0] *= spoint->alpha; + shr->combined[1] *= spoint->alpha; + shr->combined[2] *= spoint->alpha; + shr->combined[3] *= spoint->alpha; + + shr->col[0] *= spoint->alpha; + shr->col[1] *= spoint->alpha; + shr->col[2] *= spoint->alpha; + shr->col[3] *= spoint->alpha; + + shr->alpha *= spoint->alpha; + } + /* include lamphalos for strand, since halo layer was added already */ if(re->flag & R_LAMPHALO) if(shi->layflag & SCE_LAY_HALO) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 3c2969e77bf..e5bb4dd8a10 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3610,8 +3610,8 @@ static void object_panel_particle_children(Object *ob) if(part==NULL) return; block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_child", UI_EMBOSS, UI_HELV, curarea->win); - uiNewPanelTabbed("Extras", "Particle"); if(uiNewPanel(curarea, block, "Children", "Particle", 1300, 0, 318, 204)==0) return; + uiNewPanelTabbed("Extras", "Particle"); uiDefButS(block, MENU, B_PART_ALLOC_CHILD, "Children from:%t|Faces%x2|Particles%x1|None%x0", butx,buty,butw,buth, &part->childtype, 14.0, 0.0, 0, 0, "Create child particles"); @@ -3957,6 +3957,47 @@ static void object_panel_particle_visual(Object *ob) } uiBlockEndAlign(block); } +static void object_panel_particle_simplification(Object *ob) +{ + uiBlock *block; + ParticleSystem *psys=psys_get_current(ob); + ParticleSettings *part; + short butx=0, buty=160, butw=150, buth=20; + + if (psys==NULL) return; + part=psys->part; + if(part==NULL) return; + + if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) + return; + if(part->childtype!=PART_CHILD_FACES) + return; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_simplification", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Visualization", "Particle"); + if(uiNewPanel(curarea, block, "Simplification", "Particle", 640, 0, 318, 204)==0) return; + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, PART_SIMPLIFY_ENABLE, B_PART_REDRAW, "Child Simplification", butx,buty-=buth,butw,buth, &part->simplify_flag, 0, 0, 0, 0, "Remove child strands as the object becomes smaller on the screen"); + uiBlockEndAlign(block); + if(part->simplify_flag & PART_SIMPLIFY_ENABLE) { + buty -= 10; + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_NOP, "Reference Size:", butx,(buty-=buth),butw,buth, &part->simplify_refsize, 1.0, 32768.0, 0, 0, "Reference size size in pixels, after which simplification begins"); + uiDefButF(block, NUM, B_NOP, "Rate:", butx,(buty-=buth),butw,buth, &part->simplify_rate, 0.0, 1.0, 0, 0, "Speed of simplification"); + uiDefButF(block, NUM, B_NOP, "Transition:", butx,(buty-=buth),butw,buth, &part->simplify_transition, 0.0, 1.0, 0, 0, "Transition period for fading out strands"); + uiBlockEndAlign(block); + + buty -= 10; + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, PART_SIMPLIFY_VIEWPORT, B_PART_REDRAW, "Viewport", butx,buty-=buth,butw,buth, &part->simplify_flag, 0, 0, 0, 0, "Remove child strands as the object goes outside the viewport"); + uiDefButF(block, NUM, B_NOP, "Rate:", butx,(buty-=buth),butw,buth, &part->simplify_viewport, 0.0, 0.999, 0, 0, "Speed of simplification"); + uiBlockEndAlign(block); + } + uiBlockEndAlign(block); +} static void boidrule_moveDown(void *part_v, void *rule_v) { ParticleSettings *part = part_v; @@ -4700,6 +4741,7 @@ void particle_panels() if(psys){ object_panel_particle_physics(ob); object_panel_particle_visual(ob); + object_panel_particle_simplification(ob); object_panel_particle_extra(ob); object_panel_particle_children(ob); } diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index dafd156524f..ad1afcc0608 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -3852,31 +3852,37 @@ static uiBlock *strand_menu(void *mat_v) { Material *ma= mat_v; uiBlock *block; + int buth=20, butw=230, butx=10, buty=160; block= uiNewBlock(&curarea->uiblocks, "strand menu", UI_EMBOSS, UI_HELV, curarea->win); - + + if(ma->mode & MA_STR_B_UNITS) + buty += buth; + /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", 0, 0, 250, 170, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "", 0, 0, butw+20, buty+10, NULL, 0, 0, 0, 0, ""); + /* event return 0, to prevent menu to close */ uiBlockBeginAlign(block); - /* event return 0, to prevent menu to close */ - - uiDefButBitI(block, TOG, MA_TANGENT_STR, 0, "Use Tangent Shading", 10,140,230,20, &(ma->mode), 0, 0, 0, 0, "Uses direction of strands as normal for tangent-shading"); - uiDefButBitI(block, TOG, MA_STR_SURFDIFF, 0, "Surface Diffuse", 10,120,115,20, &(ma->mode), 0, 0, 0, 0, "Make diffuse shading more similar to shading the surface"); - uiDefButF(block, NUM, 0, "Dist", 125,120,115,20, &ma->strand_surfnor, 0.0f, 10.0f, 2, 0, "Distance in Blender units over which to blend in the surface normal"); + uiDefButBitI(block, TOG, MA_TANGENT_STR, 0, "Use Tangent Shading", butx,buty-=buth,butw,buth, &(ma->mode), 0, 0, 0, 0, "Uses direction of strands as normal for tangent-shading"); + uiDefButBitI(block, TOG, MA_STR_SURFDIFF, 0, "Surface Diffuse", butx,buty-=buth,butw/2,buth, &(ma->mode), 0, 0, 0, 0, "Make diffuse shading more similar to shading the surface"); + uiDefButF(block, NUM, 0, "Dist", butx+butw/2,buty,butw/2,buth, &ma->strand_surfnor, 0.0f, 10.0f, 2, 0, "Distance in Blender units over which to blend in the surface normal"); + + buty -= 5; uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_STR_B_UNITS, 0, "Use Blender Units", 10,95,230,20, &(ma->mode), 0, 0, 0, 0, "Use actual Blender units for widths instead of pixels"); + uiDefButBitI(block, TOG, MA_STR_B_UNITS, 0, "Use Blender Units", butx,buty-=buth,butw,buth, &(ma->mode), 0, 0, 0, 0, "Use actual Blender units for widths instead of pixels"); if(ma->mode & MA_STR_B_UNITS){ - uiDefButF(block, NUMSLI, 0, "Start ", 10, 75, 230,20, &ma->strand_sta, 0.0001, 2.0, 2, 0, "Start size of strands in Blender units"); - uiDefButF(block, NUMSLI, 0, "End ", 10, 55, 230,20, &ma->strand_end, 0.0001, 1.0, 2, 0, "End size of strands in Blender units"); + uiDefButF(block, NUMSLI, 0, "Start ", butx,buty-=buth, butw,buth, &ma->strand_sta, 0.0001, 2.0, 2, 0, "Start size of strands in Blender units"); + uiDefButF(block, NUMSLI, 0, "End ", butx,buty-=buth, butw,buth, &ma->strand_end, 0.0001, 1.0, 2, 0, "End size of strands in Blender units"); + uiDefButF(block, NUMSLI, 0, "Minimum ", butx,buty-=buth, butw,buth, &ma->strand_min, 0.001, 10.0, 0, 0, "Minimum size of strands in pixels"); } else{ - uiDefButF(block, NUMSLI, 0, "Start ", 10, 75, 230,20, &ma->strand_sta, 0.25, 20.0, 2, 0, "Start size of strands in pixels"); - uiDefButF(block, NUMSLI, 0, "End ", 10, 55, 230,20, &ma->strand_end, 0.25, 10.0, 2, 0, "End size of strands in pixels"); + uiDefButF(block, NUMSLI, 0, "Start ", butx,buty-=buth, butw,buth, &ma->strand_sta, 0.25, 20.0, 2, 0, "Start size of strands in pixels"); + uiDefButF(block, NUMSLI, 0, "End ", butx,buty-=buth, butw,buth, &ma->strand_end, 0.25, 10.0, 2, 0, "End size of strands in pixels"); } - uiDefButF(block, NUMSLI, 0, "Shape ", 10, 35, 230,20, &ma->strand_ease, -0.9, 0.9, 2, 0, "Shape of strands, positive value makes it rounder, negative makes it spiky"); - uiDefBut(block, TEX, B_MATPRV, "UV:", 10,10,230,20, ma->strand_uvname, 0, 31, 0, 0, "Set name of UV layer to override"); + uiDefButF(block, NUMSLI, 0, "Shape ", butx,buty-=buth, butw,buth, &ma->strand_ease, -0.9, 0.9, 2, 0, "Shape of strands, positive value makes it rounder, negative makes it spiky"); + uiDefBut(block, TEX, B_MATPRV, "UV:", butx,buty-=buth,butw,buth, ma->strand_uvname, 0, 31, 0, 0, "Set name of UV layer to override"); uiBlockSetDirection(block, UI_TOP); BIF_preview_changed(ID_MA); From 26b0261a53456d30d9aabcd9368afaeb95cf982b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 20 Dec 2007 17:04:10 +0000 Subject: [PATCH 20/99] Particle Edit Mode ================== - Added a Remove Doubles tool, to remove two particles with the same root position. --- source/blender/include/BIF_editparticle.h | 1 + source/blender/src/editobject.c | 7 +- source/blender/src/editparticle.c | 78 +++++++++++++++++++++++ source/blender/src/header_view3d.c | 4 ++ 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/source/blender/include/BIF_editparticle.h b/source/blender/include/BIF_editparticle.h index 08f5813560f..77fb091de37 100644 --- a/source/blender/include/BIF_editparticle.h +++ b/source/blender/include/BIF_editparticle.h @@ -82,6 +82,7 @@ void PE_delete_particle(void); void PE_remove_doubles(void); void PE_mirror_x(int tagged); void PE_selectbrush_menu(void); +void PE_remove_doubles(void); /* undo */ void PE_undo_push(char *str); diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index bb3beb329f1..c563548759c 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2296,9 +2296,9 @@ void special_editmenu(void) return; if(G.scene->selectmode & SCE_SELECT_POINT) - nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4"); + nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5"); else - nr= pupmenu("Specials%t|Rekey%x1"); + nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5"); switch(nr) { case 1: @@ -2315,6 +2315,9 @@ void special_editmenu(void) case 4: PE_select_tip(); break; + case 5: + PE_remove_doubles(); + break; } DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c index 0475e91f2b7..f07012c463d 100644 --- a/source/blender/src/editparticle.c +++ b/source/blender/src/editparticle.c @@ -83,6 +83,7 @@ #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_space.h" +#include "BIF_toolbox.h" #include "BSE_view.h" @@ -1901,6 +1902,83 @@ void PE_subdivide(void) BIF_undo_push("Subdivide hair(s)"); } +void PE_remove_doubles(void) +{ + Object *ob=OBACT; + ParticleSystem *psys=PE_get_current(ob); + ParticleEditSettings *pset=PE_settings(); + ParticleData *pa; + ParticleEdit *edit; + ParticleSystemModifierData *psmd; + KDTree *tree; + KDTreeNearest nearest[10]; + float mat[4][4], co[3]; + int i, n, totn, removed, totpart, flag, totremoved; + + if(!PE_can_edit(psys)) return; + + edit= psys->edit; + psmd= psys_get_modifier(ob, psys); + totremoved= 0; + + do { + removed= 0; + + totpart= psys->totpart; + tree=BLI_kdtree_new(totpart); + + /* insert particles into kd tree */ + LOOP_PARTICLES(i,pa) { + if(particle_is_selected(psys, pa)) { + psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat); + VECCOPY(co, pa->hair[0].co); + Mat4MulVecfl(mat, co); + BLI_kdtree_insert(tree, i, co, NULL); + } + } + + BLI_kdtree_balance(tree); + + /* tag particles to be removed */ + LOOP_PARTICLES(i,pa) { + if(particle_is_selected(psys, pa)) { + psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat); + VECCOPY(co, pa->hair[0].co); + Mat4MulVecfl(mat, co); + + totn= BLI_kdtree_find_n_nearest(tree,10,co,NULL,nearest); + + for(n=0; n i && nearest[n].dist < 0.0002f) { + if(!(pa->flag & PARS_TAG)) { + pa->flag |= PARS_TAG; + removed++; + } + } + } + } + } + + BLI_kdtree_free(tree); + + /* remove tagged particles - don't do mirror here! */ + flag= pset->flag; + pset->flag &= ~PE_X_MIRROR; + remove_tagged_elements(ob, psys); + pset->flag= flag; + totremoved += removed; + } while(removed); + + if(totremoved) + notice("Removed: %d", totremoved); + + PE_recalc_world_cos(ob, psys); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 1); + BIF_undo_push("Remove double particles"); +} + /************************************************/ /* Edit Brushes */ /************************************************/ diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 3a86a55a0aa..95f24c34098 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -4691,6 +4691,9 @@ void do_view3d_particlemenu(void *arg, int event) case 6: pset->flag ^= PE_X_MIRROR; break; + case 7: + PE_remove_doubles(); + break; } allqueue(REDRAWVIEW3D, 0); @@ -4713,6 +4716,7 @@ uiBlock *view3d_particlemenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mirror|Ctrl M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Doubles|W, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete...|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); if(G.scene->selectmode & SCE_SELECT_POINT) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); From c805d35c40f4dd1d15d9803636481b167d9ef6f0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 20 Dec 2007 17:08:17 +0000 Subject: [PATCH 21/99] Bugfix for strand simplification commit, made child particles from particles crash. --- source/blender/blenkernel/intern/particle_system.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index a8ccd12874e..0294596e84b 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -899,7 +899,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm /* no need to figure out distribution */ int child_nbr= (psys->renderdata)? part->ren_child_nbr: part->child_nbr; - alloc_child_particles(psys, 1.0f); + totpart= get_alloc_child_particles_tot(psys); + alloc_child_particles(psys, totpart); cpa=psys->child; for(i=0; itotpart; p++,cpa++){ From 381e8b16b4e1ae4c1d4118bf2a76882a2ad7fc18 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 20 Dec 2007 17:52:57 +0000 Subject: [PATCH 22/99] A little christmas present for the lazy coders. In your user-config.py you can now set BF_FANCY='false' and enjoy the... lack of colors --- SConstruct | 3 +++ tools/btools.py | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/SConstruct b/SConstruct index 2cacb91d103..57d818d578d 100644 --- a/SConstruct +++ b/SConstruct @@ -170,6 +170,9 @@ else: opts = btools.read_opts(optfiles, B.arguments) opts.Update(env) +if not env['BF_FANCY']: + B.bc.disable() + # disable elbeem (fluidsim) compilation? if env['BF_NO_ELBEEM'] == 1: env['CPPFLAGS'].append('-DDISABLE_ELBEEM') diff --git a/tools/btools.py b/tools/btools.py index 02d608c3cbc..6ff0f401742 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -55,7 +55,8 @@ def validate_arguments(args, bc): 'BF_VERSE_INCLUDE', 'VERSE_BUILD_BINARY', 'VERSE_BUILD_DIR', 'VERSE_REGEN_PROTO', 'BF_TWEAK_MODE', 'BF_SPLIT_SRC', - 'WITHOUT_BF_INSTALL' + 'WITHOUT_BF_INSTALL', + 'BF_FANCY', ] arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE', @@ -298,8 +299,9 @@ def read_opts(cfg, args): (BoolOption('BF_BUILDINFO', 'Buildtime in splash if true', 'true')), (BoolOption('BF_TWEAK_MODE', 'Enable tweak mode if true', 'false')), - (BoolOption('BF_SPLIT_SRC', 'Split src lib into several chunks if true', 'false')), + (BoolOption('BF_SPLIT_SRC', 'Split src lib into several chunks if true', 'false')), (BoolOption('WITHOUT_BF_INSTALL', 'dont install if true', 'false')), + (BoolOption('BF_FANCY', 'Enable fancy output if true', 'true')), ) # end of opts.AddOptions() From 1d8fdff9094b5adadd08dd0fad9265d28d89bdd7 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 20 Dec 2007 18:41:11 +0000 Subject: [PATCH 23/99] Reset GL lights are reloading defaults with Ctrl-X. GL Lights defaults are read back from the file, they just weren't applied until the next recalc call. --- source/blender/src/toets.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index ad7c1b4069b..53bbfb3fb69 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -948,6 +948,11 @@ int blenderqread(unsigned short event, short val) if(G.qual==LR_CTRLKEY) { if(okee("Erase all")) { if( BIF_read_homefile(0)==0) error("No file ~/.B.blend"); + + /* Reset lights + * This isn't done when reading userdef, do it now + * */ + default_gl_light(); } return 0; } From 801c0799c104872f68fe74597e22c09960cce120 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Thu, 20 Dec 2007 19:07:47 +0000 Subject: [PATCH 24/99] == Sculpt Mode == Applying Stephan Kassemeyer's patch (#6750) to add a curve modifier for sculpting. A few changes from the patch: * The default curve is closer to the old behavior * Fixed loading files already saved in sculpt mode * Changed the interface; split the brush texture controls off into a third sculpt tab, and put the curve (and curve reset) into the Brush tab. --- .../blender/blenkernel/BKE_bad_level_calls.h | 2 + .../blenkernel/bad_level_call_stubs/stubs.c | 1 + source/blender/blenloader/intern/readfile.c | 6 ++ source/blender/blenloader/intern/writefile.c | 2 + source/blender/include/BDR_sculptmode.h | 2 + source/blender/makesdna/DNA_scene_types.h | 3 + source/blender/src/buttons_editing.c | 76 +++++++++++++------ source/blender/src/drawview.c | 2 +- source/blender/src/sculptmode.c | 49 ++++++++++-- 9 files changed, 114 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 8b9454f1a9d..02e2f799103 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -217,6 +217,8 @@ void multires_update_levels(struct Mesh *me, const int render); void multires_calc_level_maps(struct MultiresLevel *lvl); struct Multires *multires_copy(struct Multires *orig); /* sculptmode.c */ +struct SculptData; +void sculpt_reset_curve(struct SculptData *sd); void sculptmode_free_all(struct Scene *sce); void sculptmode_init(struct Scene *sce); diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 55931b50462..e0aa288c7b2 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -317,6 +317,7 @@ void multires_set_level(struct Object *ob, struct Mesh *me, const int render) {} void multires_update_levels(struct Mesh *me, const int render) {} void multires_calc_level_maps(struct MultiresLevel *lvl) {} struct Multires *multires_copy(struct Multires *orig) {return NULL;} +void sculpt_reset_curve(struct SculptData *sd) {} void sculptmode_init(struct Scene *sce) {} void sculptmode_free_all(struct Scene *sce) {} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8bbcc7016c1..553ab0eb168 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3323,6 +3323,12 @@ static void direct_link_scene(FileData *fd, Scene *sce) /* SculptData textures */ for(a=0; asculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]); + /* Sculpt intensity curve */ + sce->sculptdata.cumap= newdataadr(fd, sce->sculptdata.cumap); + if(sce->sculptdata.cumap) + direct_link_curvemapping(fd, sce->sculptdata.cumap); + else + sculpt_reset_curve(&sce->sculptdata); if(sce->ed) { ListBase *old_seqbasep= &((Editing *)sce->ed)->seqbase; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index cfaae977bdd..d19c634e610 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1422,6 +1422,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase) for(a=0; asculptdata.mtex[a]); + if(sce->sculptdata.cumap) + write_curvemapping(wd, sce->sculptdata.cumap); ed= sce->ed; if(ed) { diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h index c80f9ea8626..abbb17ac42b 100644 --- a/source/blender/include/BDR_sculptmode.h +++ b/source/blender/include/BDR_sculptmode.h @@ -99,12 +99,14 @@ SculptSession *sculpt_session(void); struct SculptData *sculpt_data(void); /* Memory */ +void sculpt_reset_curve(struct SculptData *sd); void sculptmode_init(struct Scene *); void sculptmode_free_all(struct Scene *); void sculptmode_correct_state(void); /* Interface */ void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy); +void sculptmode_draw_interface_brush(struct uiBlock *block,unsigned short cx, unsigned short cy); void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy); void sculptmode_rem_tex(void*,void*); void sculptmode_propset_init(PropsetMode mode); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 412c40c7eb0..c82a1f9e510 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -424,6 +424,9 @@ typedef struct SculptData /* Pointers to all of sculptmodes's textures */ struct MTex *mtex[10]; + /* Editable brush shape */ + struct CurveMapping *cumap; + /* Settings for each brush */ BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush, flattenbrush; short brush_type; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 83139fcfb0a..ca878933499 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -5046,10 +5046,18 @@ void editing_panel_sculpting_tools() sculptmode_draw_interface_tools(block,0,200); } +void editing_panel_sculpting_brush() +{ + uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_brush", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Brush", "Editing", 300, 0, 318, 204)==0) return; + + sculptmode_draw_interface_brush(block,0,200); +} + void editing_panel_sculpting_textures() { - uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_textures", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Brush", "Editing", 300, 0, 318, 204)==0) return; + uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_texture", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Texture", "Editing", 300, 0, 318, 204)==0) return; sculptmode_draw_interface_textures(block,0,200); } @@ -5057,11 +5065,10 @@ void editing_panel_sculpting_textures() void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned short cy) { SculptData *sd; - uiBut *but; if(!G.scene) return; sd= &G.scene->sculptdata; - + uiBlockBeginAlign(block); uiDefBut(block,LABEL,B_NOP,"Brush",cx,cy,90,19,NULL,0,0,0,0,""); @@ -5090,7 +5097,7 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned if(sd->brush_type!=GRAB_BRUSH) uiDefButC(block,TOG,B_NOP,"Airbrush",cx+178,cy,89,19,&sculptmode_brush()->airbrush,0,0,0,0,"Brush makes changes without waiting for the mouse to move"); cy-= 20; - but= uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels"); + uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels"); cy-= 20; if(sd->brush_type!=GRAB_BRUSH) uiDefButC(block,NUMSLI,B_NOP,"Strength: ",cx,cy,268,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength"); @@ -5109,6 +5116,46 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned cx+= 210; } +static void sculptmode_curves_reset(void *sd_v, void *j) +{ + SculptData *sd = sd_v; + sculpt_reset_curve(sd); + curvemapping_changed(sd->cumap, 0); +} + +void sculptmode_draw_interface_brush(uiBlock *block, unsigned short cx, unsigned short cy) +{ + SculptData *sd= sculpt_data(); + int orig_y = cy; + rctf rect; + uiBut *but; + + uiBlockBeginAlign(block); + cy-= 20; + uiDefButC(block,TOG,REDRAWBUTSEDIT, "Curve", cx,cy,80,19, &sd->texfade, 0,0,0,0,"Use curve control for radial brush intensity"); + cy-= 20; + but= uiDefBut(block, BUT, REDRAWBUTSEDIT, "Reset",cx,cy,80,19, NULL, 0,0,0,0, "Default curve preset"); + uiButSetFunc(but, sculptmode_curves_reset, sd, NULL); + cy-= 25; + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefButS(block,NUM,B_NOP, "Space", cx,cy,80,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots"); + cy-= 20; + if(sd->brush_type == DRAW_BRUSH) + uiDefButC(block,NUM,B_NOP, "View", cx,cy,80,19, &sculptmode_brush()->view, 0,10,20,0,"Pulls brush direction towards view"); + uiBlockEndAlign(block); + + /* Draw curve */ + cx += 90; + cy = orig_y; + rect.xmin= cx; rect.xmax= cx + 178; + rect.ymin= cy - 160; rect.ymax= cy + 20; + uiBlockBeginAlign(block); + curvemap_buttons(block, sd->cumap, (char)0, B_NOP, 0, &rect); + uiBlockEndAlign(block); +} + void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsigned short cy) { SculptData *sd= sculpt_data(); @@ -5119,24 +5166,7 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig uiBut *but; uiBlockBeginAlign(block); - uiDefBut(block,LABEL,B_NOP,"Common",cx,cy,80,20,0,0,0,0,0,""); cy-= 20; - - uiBlockBeginAlign(block); - uiDefButC(block,TOG,B_NOP, "Fade", cx,cy,80,19, &sd->texfade, 0,0,0,0,"Smooth the edges of the texture"); - cy-= 20; - uiDefButS(block,NUM,B_NOP, "Space", cx,cy,80,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots"); - cy-= 20; - if(sd->brush_type == DRAW_BRUSH) - uiDefButC(block,NUM,B_NOP, "View", cx,cy,80,19, &sculptmode_brush()->view, 0,10,20,0,"Pulls brush direction towards view"); - uiBlockEndAlign(block); - - cy= orig_y; - cx+= 85; - uiBlockBeginAlign(block); - uiDefBut(block,LABEL,B_NOP,"Texture",cx,cy,80,20,0,0,0,0,0,""); - cy-= 20; - /* TEX CHANNELS */ uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_NEUTRAL); @@ -6034,6 +6064,8 @@ void editing_panels() uiNewPanelTabbed("Multires", "Editing"); editing_panel_sculpting_tools(); uiNewPanelTabbed("Multires", "Editing"); + editing_panel_sculpting_brush(); + uiNewPanelTabbed("Multires", "Editing"); editing_panel_sculpting_textures(); } else { if(G.f & (G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT) ) { diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index b3ffd1263ad..5df1448ebc1 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2252,7 +2252,7 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT uiSetPanelHandler(VIEW3D_HANDLER_OBJECT); // for close and esc if((G.f & G_SCULPTMODE) && !G.obedit) { - if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 425, 234)) + if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 234)) return; } else if(G.f & G_PARTICLEEDIT && !G.obedit){ if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 234)) diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c index 7dd668e1acb..010bf6f746c 100644 --- a/source/blender/src/sculptmode.c +++ b/source/blender/src/sculptmode.c @@ -53,6 +53,7 @@ #include "DNA_texture_types.h" #include "DNA_view3d_types.h" #include "DNA_userdef_types.h" +#include "DNA_color_types.h" #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" @@ -66,6 +67,7 @@ #include "BKE_modifier.h" #include "BKE_texture.h" #include "BKE_utildefines.h" +#include "BKE_colortools.h" #include "BIF_editkey.h" #include "BIF_editview.h" @@ -190,6 +192,35 @@ SculptSession *sculpt_session(void) * Allocate/initialize/free data */ +// Default curve approximates 0.5 * (cos(pi * x) + 1), with 0 <= x <= 1; +void sculpt_reset_curve(SculptData *sd) +{ + CurveMap *cm = NULL; + + if(!sd->cumap) + sd->cumap = curvemapping_add(1, 0, 0, 1, 1); + + cm = sd->cumap->cm; + + if(cm->curve) + MEM_freeN(cm->curve); + cm->curve= MEM_callocN(6*sizeof(CurveMapPoint), "curve points"); + cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; + cm->totpoint= 6; + cm->curve[0].x= 0; + cm->curve[0].y= 1; + cm->curve[1].x= 0.1; + cm->curve[1].y= 0.97553; + cm->curve[2].x= 0.3; + cm->curve[2].y= 0.79389; + cm->curve[3].x= 0.9; + cm->curve[3].y= 0.02447; + cm->curve[4].x= 0.7; + cm->curve[4].y= 0.20611; + cm->curve[5].x= 1; + cm->curve[5].y= 0; +} + /* Initialize 'permanent' sculpt data that is saved with file kept after switching out of sculptmode. */ void sculptmode_init(Scene *sce) @@ -203,6 +234,9 @@ void sculptmode_init(Scene *sce) sd= &sce->sculptdata; + if(sd->cumap) + curvemapping_free(sd->cumap); + memset(sd, 0, sizeof(SculptData)); sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size = @@ -227,6 +261,7 @@ void sculptmode_init(Scene *sce) sd->tablet_size=3; sd->tablet_strength=10; sd->rake=0; + sculpt_reset_curve(sd); } void sculptmode_free_session(Scene *); @@ -281,6 +316,9 @@ void sculptmode_free_all(Scene *sce) MEM_freeN(mtex); } } + + curvemapping_free(sd->cumap); + sd->cumap = NULL; } /* vertex_users is an array of Lists that store all the faces that use a @@ -735,12 +773,11 @@ void do_flatten_brush(const EditData *e, const ListBase *active_verts) } } -/* Creates a smooth curve for the brush shape. This is the cos(x) curve from - [0,PI] scaled to [0,len]. The range is scaled to [0,1]. */ -float simple_strength(float p, const float len) +/* Uses the brush curve control to find a strength value between 0 and 1 */ +float curve_strength(float p, const float len) { if(p > len) p= len; - return 0.5f * (cos(M_PI*p/len) + 1); + return curvemapping_evaluateF(G.scene->sculptdata.cumap, 0, p/len); } /* Uses symm to selectively flip any axis of a coordinate. */ @@ -883,7 +920,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin } if(sd->texfade) - avg*= simple_strength(len,e->size); /* Smooth curve */ + avg*= curve_strength(len,e->size); /* Smooth curve */ return avg; } @@ -1323,7 +1360,7 @@ void sculptmode_propset_calctex() for(j=0; jtexfade) - pd->texdata[i*tsz+j]= simple_strength(magn,tsz/2); + pd->texdata[i*tsz+j]= curve_strength(magn,tsz/2); else pd->texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0; } From 6135f9710561d12640c8b5cb3b654237c80cf88f Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Thu, 20 Dec 2007 19:39:21 +0000 Subject: [PATCH 25/99] Need to propigate -m64 flags to compile verse. Kent --- extern/verse/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/verse/Makefile b/extern/verse/Makefile index 2e88ee2223f..bd8bba33195 100644 --- a/extern/verse/Makefile +++ b/extern/verse/Makefile @@ -54,5 +54,5 @@ install: all debug ifeq ($(OS),darwin) ranlib $(NAN_VERSE)/lib/libverse.a endif - $(CCC) $(LDFLAGS) -o $(DIR)/verse$(EXT) $(DIR)/libverse.a $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS) + $(CCC) $(CCFLAGS) $(LDFLAGS) -o $(DIR)/verse$(EXT) $(DIR)/libverse.a $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS) @$(CP) $(DIR)/verse$(EXT) $(OCGDIR)/bin From 1a475f0dfc3c76021579c140c9840a61cc0bac11 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 21 Dec 2007 01:53:55 +0000 Subject: [PATCH 26/99] == Transform feature test == Related to bug [#7792] ("Around Selection" user preference doesn't work for linked objects), this commit makes Linked objects be considered in Transform. This has a couple of effects: Linked objects are used to calculate the center of transformation and such but are skipped during the actual transformation. Linked objects can be used as orbiting targets (see previously mentionned bug). The offshot is that selecting a linked object and hitting G doesn't cancel immediately as it did before (this could eventually be worked around, but I don't think it's that much of a problem. Disagreeing people should express themselves). --- source/blender/src/transform_conversions.c | 21 ++++++++++++++------- source/blender/src/transform_generics.c | 5 +++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 405168f6654..ac13634532b 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -3368,19 +3368,21 @@ static void createTransObject(TransInfo *t) /* count */ for(base= FIRSTBASE; base; base= base->next) { - if TESTBASELIB(base) { + if TESTBASE(base) { ob= base->object; /* store ipo keys? */ - if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { + if (ob->id.lib == 0 && ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { elems.first= elems.last= NULL; make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */ pushdata(&elems, sizeof(ListBase)); - for(ik= elems.first; ik; ik= ik->next) t->total++; + for(ik= elems.first; ik; ik= ik->next) + t->total++; - if(elems.first==NULL) t->total++; + if(elems.first==NULL) + t->total++; } else { t->total++; @@ -3398,15 +3400,20 @@ static void createTransObject(TransInfo *t) tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension"); for(base= FIRSTBASE; base; base= base->next) { - if TESTBASELIB(base) { + if TESTBASE(base) { ob= base->object; - td->flag= TD_SELECTED; + td->flag = TD_SELECTED; td->protectflag= ob->protectflag; td->ext = tx; + /* select linked objects, but skip them later */ + if (ob->id.lib != 0) { + td->flag |= TD_SKIP; + } + /* store ipo keys? */ - if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { + if(ob->id.lib == 0 && ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { popfirst(&elems); // bring back pushed listbase diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index d0ca1f4cd74..b24f9bea48d 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -190,8 +190,9 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) break; if (td->loc==NULL) break; - if (td->flag & TD_SKIP) - continue; + + if (td->flag & TD_SKIP) + continue; VecCopyf(loc, td->loc); VecCopyf(iloc, td->iloc); From 3d24160231f97b2d52aa81c49207ecfc19b27dad Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 21 Dec 2007 09:30:37 +0000 Subject: [PATCH 27/99] -m64 somehow made opengl headers have conflicting values when compiling. --- source/nan_compile.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/nan_compile.mk b/source/nan_compile.mk index c723ff4bfc6..a5f0dccce35 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -182,10 +182,10 @@ ifeq ($(OS),solaris) # CFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned" # CCFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned" - ifeq ($(findstring 64,$(CPU)), 64) - CFLAGS += -m64 - CCFLAGS += -m64 - endif +# ifeq ($(findstring 64,$(CPU)), 64) +# CFLAGS += -m64 +# CCFLAGS += -m64 +# endif REL_CFLAGS += -O2 REL_CCFLAGS += -O2 From 276e0569129979fc115d8a8de51c2698ea55f2f6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 21 Dec 2007 10:57:02 +0000 Subject: [PATCH 28/99] Bugfix for strand simplification, without random distribution enabled. Bugfix (hopefully) for missing strands on render bug, probably related to preview render. --- source/blender/blenkernel/intern/particle.c | 4 ++-- source/blender/blenkernel/intern/particle_system.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 32f1795747a..d0bf8b412ef 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -257,8 +257,8 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys) return 0; psmd= psys_get_modifier(ob, psys); - if(G.rendering) { - if(!psys->renderdata || !(psmd->modifier.mode & eModifierMode_Render)) + if(psys->renderdata) { + if(!(psmd->modifier.mode & eModifierMode_Render)) return 0; } else if(!(psmd->modifier.mode & eModifierMode_Realtime)) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 0294596e84b..db571f01b1e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1124,7 +1124,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm for(i=0;iflag&PART_TRAND){ + if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) { float pos; for(p=0; p Date: Sat, 22 Dec 2007 03:47:19 +0000 Subject: [PATCH 29/99] Bugfix #7854: Adding Meta/Text Object causes Blender to go into EditMode (setting disabled) This was caused by a few missing checks for this setting in the appropriate places. --- source/blender/src/editfont.c | 4 +++- source/blender/src/editmball.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c index a3de5d03283..70365c9b234 100644 --- a/source/blender/src/editfont.c +++ b/source/blender/src/editfont.c @@ -58,6 +58,7 @@ #include "DNA_scene_types.h" #include "DNA_text_types.h" #include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" #include "BKE_depsgraph.h" #include "BKE_font.h" @@ -1186,7 +1187,8 @@ void add_primitiveFont(int dummy_argument) cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox"); cu->tb[0].w = cu->tb[0].h = 0.0; - enter_editmode(EM_WAITCURSOR); + if (U.flag & USER_ADD_EDITMODE) + enter_editmode(EM_WAITCURSOR); allqueue(REDRAWALL, 0); } diff --git a/source/blender/src/editmball.c b/source/blender/src/editmball.c index 06b2e8b5dd7..71fbf834c17 100644 --- a/source/blender/src/editmball.c +++ b/source/blender/src/editmball.c @@ -49,6 +49,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" #include "BKE_utildefines.h" #include "BKE_depsgraph.h" @@ -132,6 +133,7 @@ void add_primitiveMball(int dummy_argument) { MetaElem *ml; float *curs, mat[3][3], cent[3], imat[3][3], cmat[3][3]; + short newob= 0; if(G.scene->id.lib) return; @@ -150,6 +152,7 @@ void add_primitiveMball(int dummy_argument) make_editMball(); setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + newob= 1; } /* deselect */ @@ -222,7 +225,15 @@ void add_primitiveMball(int dummy_argument) DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); // added ball can influence others - countall(); + countall(); + + /* if a new object was created, it stores it in Mball, for reload original data and undo */ + if ( !(newob) || (U.flag & USER_ADD_EDITMODE)) { + if(newob) load_editMball(); + } else { + exit_editmode(2); + } + allqueue(REDRAWALL, 0); BIF_undo_push("Add MetaElem"); } From 849b929c25073326a07b2f8e9d7d1375f27b5357 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 22 Dec 2007 10:30:50 +0000 Subject: [PATCH 30/99] small cleanup for sequencer drawing, text isn't drawn for strips when too narrow and some improvements to the strip draw loop. --- source/blender/src/drawseq.c | 80 +++++++++++++++++------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 9dbac590d30..6213b669530 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -93,11 +93,11 @@ #define SEQ_STRIP_OFSTOP 0.8 int no_rightbox=0, no_leftbox= 0; -static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction); +static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, float pixelx, short direction); static void draw_seq_extensions(Sequence *seq, SpaceSeq *sseq); static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2); static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2); -static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq); +static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq, int outline_tint, float pixelx); static char *give_seqname(Sequence *seq) { @@ -370,11 +370,10 @@ static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2, i } /* draw a handle, for each end of a sequence strip */ -static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction) +static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, float pixelx, short direction) { float v1[2], v2[2], v3[2], rx1=0, rx2=0; //for triangles and rect float x1, x2, y1, y2; - float pixelx; float handsize; float minhandle, maxhandle; char str[120]; @@ -388,7 +387,6 @@ static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction) y2= seq->machine+SEQ_STRIP_OFSTOP; v2d = &sseq->v2d; - pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin); /* clamp handles to defined size in pixel space */ handsize = seq->handsize; @@ -684,13 +682,12 @@ Draw a sequence strip, bounds check alredy made ScrArea is currently only used to get the windows width in pixels so wave file sample drawing precission is zoom adjusted */ -static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq) +static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq, int outline_tint, float pixelx) { float x1, x2, y1, y2; char col[3], is_single_image; - Sequence *last_seq = get_last_seq(); - /* we need to know if this is a single image or not for drawing */ + /* we need to know if this is a single image/color or not for drawing */ is_single_image = (char)check_single_seq(seq); /* body */ @@ -718,8 +715,8 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq) if (!is_single_image) draw_seq_extensions(seq, sseq); - draw_seq_handle(seq, sseq, SEQ_LEFTHANDLE); - draw_seq_handle(seq, sseq, SEQ_RIGHTHANDLE); + draw_seq_handle(seq, sseq, pixelx, SEQ_LEFTHANDLE); + draw_seq_handle(seq, sseq, pixelx, SEQ_RIGHTHANDLE); /* draw the strip outline */ x1= seq->startdisp; @@ -731,10 +728,9 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq) col[0]= 255; col[1]= col[2]= 40; } else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120); } - else if (seq == last_seq) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120); - else if (seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -150); - else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -60); + BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint); + glColor3ubv((GLubyte *)col); gl_round_box_shade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0); @@ -753,7 +749,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq) else if(x2>G.v2d->cur.xmax) x2= G.v2d->cur.xmax; /* nice text here would require changing the view matrix for texture text */ - if(x1 != x2) { + if( (x2-x1) / pixelx > 32) { draw_seq_text(seq, x1, x2, y1, y2); } } @@ -1386,6 +1382,7 @@ void drawseqspace(ScrArea *sa, void *spacedata) boundbox_seq(); calc_ipogrid(); + /* Alternating horizontal stripes */ i= MAX2(1, ((int)G.v2d->cur.ymin)-1); glBegin(GL_QUADS); @@ -1422,36 +1419,35 @@ void drawseqspace(ScrArea *sa, void *spacedata) /* sequences: first deselect */ if(ed) { - seq= ed->seqbasep->first; - while(seq) { /* bound box test, dont draw outside the view */ - if (seq->flag & SELECT || - MIN2(seq->startdisp, seq->start) > v2d->cur.xmax || - MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin || - seq->machine+1.0 < v2d->cur.ymin || - seq->machine > v2d->cur.ymax) - { - /* dont draw */ - } else { - draw_seq_strip(seq, sa, sseq); + Sequence *last_seq = get_last_seq(); + int sel = 0, j; + int outline_tint; + float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin); + /* loop through twice, first unselected, then selected */ + for (j=0; j<2; j++) { + seq= ed->seqbasep->first; + if (j==0) outline_tint = -150; + else outline_tint = -60; + + while(seq) { /* bound box test, dont draw outside the view */ + if ( ((seq->flag & SELECT) == sel) || + seq == last_seq || + MIN2(seq->startdisp, seq->start) > v2d->cur.xmax || + MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin || + seq->machine+1.0 < v2d->cur.ymin || + seq->machine > v2d->cur.ymax) + { + /* dont draw */ + } else { + draw_seq_strip(seq, sa, sseq, outline_tint, pixelx); + } + seq= seq->next; } - seq= seq->next; + sel= SELECT; /* draw selected next time round */ } - } - ed= G.scene->ed; - if(ed) { - seq= ed->seqbasep->first; - while(seq) { /* bound box test, dont draw outside the view */ - if (!(seq->flag & SELECT) || - MIN2(seq->startdisp, seq->start) > v2d->cur.xmax || - MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin || - seq->machine+1.0 < v2d->cur.ymin || - seq->machine > v2d->cur.ymax) - { - /* dont draw */ - } else { - draw_seq_strip(seq, sa, sseq); - } - seq= seq->next; + /* draw the last selected last, removes some overlapping error */ + if (last_seq) { + draw_seq_strip(last_seq, sa, sseq, 120, pixelx); } } From a000473d9d9c406b69caa55acb9e8394e5b2fcc5 Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sat, 22 Dec 2007 12:05:27 +0000 Subject: [PATCH 31/99] -> Alpha Clip Tweak Apparently on some cards/drivers setting alpha clip to 1.0 will make every pixel get clipped out regardless of its associated alpha value being 1.0. Added a fix for this. --- source/blender/src/drawmesh.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index 3c98888ead9..df5334dd27d 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -241,9 +241,13 @@ int set_tpage(MTFace *tface) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* added after 2.45 to clip alpha */ - glEnable ( GL_ALPHA_TEST ); - glAlphaFunc ( GL_GREATER, U.glalphaclip ); + /*if U.glalphaclip == 1.0, some cards go bonkers... turn off alpha test in this case*/ + if(U.glalphaclip == 1.0) glDisable(GL_ALPHA_TEST); + else{ + glEnable ( GL_ALPHA_TEST ); + glAlphaFunc ( GL_GREATER, U.glalphaclip ); + } /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ } From 6f730601af1e169bb80a2f73839dea8091211b5c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 22 Dec 2007 17:16:06 +0000 Subject: [PATCH 32/99] Text draw assumed curarea->spacedata.first was always a text space - which in some cases is not correct. This fixes a crash where python changing screens then raising an error would cause a crash. --- source/blender/include/BIF_drawtext.h | 2 +- source/blender/src/drawtext.c | 62 ++++++++++---------- source/blender/src/header_text.c | 82 ++++++++++++++++++--------- 3 files changed, 86 insertions(+), 60 deletions(-) diff --git a/source/blender/include/BIF_drawtext.h b/source/blender/include/BIF_drawtext.h index a63e2bb264d..6950f3ba215 100644 --- a/source/blender/include/BIF_drawtext.h +++ b/source/blender/include/BIF_drawtext.h @@ -47,7 +47,7 @@ void add_text_fs(char *file); void free_txt_data(void); void pop_space_text(struct SpaceText *st); -void get_format_string(void); +void get_format_string(struct SpaceText *st); void do_brackets(void); #endif diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c index 0b33a4df5fc..b4026746a35 100644 --- a/source/blender/src/drawtext.c +++ b/source/blender/src/drawtext.c @@ -167,15 +167,13 @@ void free_txt_data(void) { if (temp_char_accum) MEM_freeN(temp_char_accum); } -static int render_string (char *in) { - SpaceText *st= curarea->spacedata.first; +static int render_string (SpaceText *st, char *in) { int r = 0, i = 0; while(*in) { if (*in=='\t') { if (temp_char_pos && *(in-1)=='\t') i= st->tabnumber; else if (st->tabnumber > 0) i= st->tabnumber - (temp_char_pos%st->tabnumber); - while(i--) temp_char_write(' ', r); } else temp_char_write(*in, r); @@ -188,9 +186,8 @@ static int render_string (char *in) { return r; } -void get_format_string(void) +void get_format_string(SpaceText *st) { - SpaceText *st = curarea->spacedata.first; Text *text = st->text; TextLine *tmp; char *in_line; @@ -538,7 +535,7 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra char *in; int *acc; - w= render_string(str); + w= render_string(st, str); if(wleft; - w= render_string((*linep)->line); + w= render_string(st, (*linep)->line); if(xlen; @@ -996,6 +993,8 @@ void drawtextspace(ScrArea *sa, void *spacedata) float col[3]; int linecount = 0; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + BIF_GetThemeColor3fv(TH_BACK, col); glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -1030,7 +1029,7 @@ void drawtextspace(ScrArea *sa, void *spacedata) if(st->showsyntax) { if (tmp && !tmp->format) { - get_format_string(); + get_format_string(st); } } @@ -1080,13 +1079,12 @@ void pop_space_text (SpaceText *st) if (st->left <0) st->left= 0; } -void add_text_fs(char *file) +void add_text_fs(char *file) /* bad but cant pass an as arg here */ { SpaceText *st= curarea->spacedata.first; Text *text; - if (!st) return; - if (st->spacetype != SPACE_TEXT) return; + if (st==NULL || st->spacetype != SPACE_TEXT) return; text= add_text(file); @@ -1094,7 +1092,7 @@ void add_text_fs(char *file) st->top= 0; - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); allqueue(REDRAWTEXT, 0); allqueue(REDRAWHEADERS, 0); } @@ -1466,9 +1464,11 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) short val= evt->val; char ascii= evt->ascii; SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + Text *text; int do_draw=0, p; - + + if (st==NULL || st->spacetype != SPACE_TEXT) return; + /* smartass code to prevent the CTRL/ALT events below from not working! */ if(G.qual & (LR_ALTKEY|LR_CTRLKEY)) if(!ispunct(ascii)) @@ -1580,7 +1580,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } } else if (ascii) { if (txt_add_char(text, ascii)) { - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); pop_space_text(st); do_draw= 1; } @@ -1612,11 +1612,11 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) txt_order_cursors(text); uncomment(text); do_draw = 1; - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); break; } else if (G.qual == LR_CTRLKEY) { txt_delete_char(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; pop_space_text(st); } @@ -1634,7 +1634,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case 2: txt_paste(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; break; case 3: @@ -1722,7 +1722,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if (okee("Reopen text")) { if (!reopen_text(text)) error("Could not reopen file"); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); } do_draw= 1; } @@ -1766,7 +1766,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } if (G.qual == LR_ALTKEY) { txt_do_undo(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; } break; /* BREAK U */ @@ -1800,7 +1800,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) txt_paste_clipboard(text); else txt_paste(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; pop_space_text(st); } @@ -1808,7 +1808,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) case XKEY: if (G.qual == LR_ALTKEY || G.qual == LR_CTRLKEY) { txt_cut_sel(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; pop_space_text(st); } @@ -1820,7 +1820,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else { txt_do_undo(text); } - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; } break; @@ -1839,7 +1839,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) txt_add_char(text, '\t'); } } - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); pop_space_text(st); do_draw= 1; st->currtab_set = setcurr_tab(text); @@ -1858,20 +1858,20 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } } } - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; pop_space_text(st); break; case BACKSPACEKEY: txt_backspace_char(text); set_tabs(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; pop_space_text(st); break; case DELKEY: txt_delete_char(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); do_draw= 1; pop_space_text(st); st->currtab_set = setcurr_tab(text); @@ -2138,18 +2138,18 @@ void convert_tabs (struct SpaceText *st, int tab) //first convert to all space, this make it alot easier to convert to tabs because there is no mixtures of ' ' && '\t' while(tmp) { check_line = tmp->line; - new_line = MEM_mallocN(render_string(check_line)+1, "Converted_Line"); - format = MEM_mallocN(render_string(check_line)+1, "Converted_Syntax_format"); + new_line = MEM_mallocN(render_string(st, check_line)+1, "Converted_Line"); + format = MEM_mallocN(render_string(st, check_line)+1, "Converted_Syntax_format"); j = 0; for (a=0; a < strlen(check_line); a++) { //foreach char in line if(check_line[a] == '\t') { //checking for tabs //get the number of spaces this tabs is showing //i dont like doing it this way but will look into it later new_line[j] = '\0'; - number = render_string(new_line); + number = render_string(st, new_line); new_line[j] = '\t'; new_line[j+1] = '\0'; - number = render_string(new_line)-number; + number = render_string(st, new_line)-number; for(extra = 0; extra < number; extra++) { new_line[j] = ' '; j++; diff --git a/source/blender/src/header_text.c b/source/blender/src/header_text.c index 04c354fb2b1..728edc76a9c 100644 --- a/source/blender/src/header_text.c +++ b/source/blender/src/header_text.c @@ -79,13 +79,12 @@ void do_text_buttons(unsigned short event) { - SpaceText *st= curarea->spacedata.first; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ ID *id, *idtest; int nr= 1; Text *text; - - if (!st) return; - if (st->spacetype != SPACE_TEXT) return; + + if (st==NULL || st->spacetype != SPACE_TEXT) return; switch (event) { case B_TEXTBROWSE: @@ -132,7 +131,7 @@ void do_text_buttons(unsigned short event) st->top= 0; pop_space_text(st); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); allqueue(REDRAWTEXT, 0); allqueue(REDRAWHEADERS, 0); } @@ -230,13 +229,13 @@ void do_text_buttons(unsigned short event) break; case B_TAB_NUMBERS: - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); allqueue(REDRAWTEXT, 0); allqueue(REDRAWHEADERS, 0); break; case B_SYNTAX: if (st->showsyntax) { - get_format_string(); + get_format_string(st); } allqueue(REDRAWTEXT, 0); allqueue(REDRAWHEADERS, 0); @@ -278,10 +277,14 @@ static uiBlock *text_template_scriptsmenu (void *args_unused) /* action executed after clicking in File menu */ static void do_text_filemenu(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + Text *text; ScrArea *sa; - + + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text= st->text; + switch(event) { case 1: st->text= add_empty_text( "Text" ); @@ -300,7 +303,7 @@ static void do_text_filemenu(void *arg, int event) if (!reopen_text(text)) { error("Could not reopen file"); } - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); } break; case 5: @@ -361,10 +364,14 @@ static void do_text_filemenu(void *arg, int event) /* action executed after clicking in Edit menu */ static void do_text_editmenu(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + Text *text; ScrArea *sa; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text= st->text; + switch(event) { case 1: txt_do_undo(text); @@ -381,7 +388,7 @@ static void do_text_editmenu(void *arg, int event) break; case 5: txt_paste(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); break; case 6: txt_print_cutbuffer(); @@ -410,10 +417,14 @@ static void do_text_editmenu(void *arg, int event) /* action executed after clicking in View menu */ static void do_text_editmenu_viewmenu(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + Text *text; ScrArea *sa; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text = st->text; + switch(event) { case 1: txt_move_bof(text, 0); @@ -438,10 +449,14 @@ static void do_text_editmenu_viewmenu(void *arg, int event) /* action executed after clicking in Select menu */ static void do_text_editmenu_selectmenu(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + Text *text; ScrArea *sa; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text = st->text; + switch(event) { case 1: txt_sel_all(text); @@ -464,10 +479,14 @@ static void do_text_editmenu_selectmenu(void *arg, int event) /* action executed after clicking in Format menu */ static void do_text_formatmenu(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + Text *text; ScrArea *sa; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text = st->text; + switch(event) { case 3: if (txt_has_sel(text)) { @@ -490,7 +509,7 @@ static void do_text_formatmenu(void *arg, int event) if ( txt_has_sel(text)) { txt_order_cursors(text); comment(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); break; } break; @@ -498,7 +517,7 @@ static void do_text_formatmenu(void *arg, int event) if ( txt_has_sel(text)) { txt_order_cursors(text); uncomment(text); - if (st->showsyntax) get_format_string(); + if (st->showsyntax) get_format_string(st); break; } break; @@ -552,7 +571,9 @@ static uiBlock *text_editmenu_selectmenu(void *arg_unused) void do_text_formatmenu_convert(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + + if (st==NULL || st->spacetype != SPACE_TEXT) return; switch(event) { case 1: convert_tabs(st, 0); break; @@ -611,8 +632,11 @@ static uiBlock *text_formatmenu(void *arg_unused) /* action executed after clicking in Object to 3d Sub Menu */ void do_text_editmenu_to3dmenu(void *arg, int event) { - SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ + Text *text; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text = st->text; switch(event) { case 1: txt_export_to_object(text); break; @@ -680,7 +704,7 @@ static uiBlock *text_editmenu(void *arg_unused) /* File menu */ static uiBlock *text_filemenu(void *arg_unused) { - SpaceText *st= curarea->spacedata.first; + SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */ Text *text= st->text; uiBlock *block; short yco= 0, menuwidth=120; @@ -728,11 +752,13 @@ void text_buttons(void) { uiBlock *block; SpaceText *st= curarea->spacedata.first; - Text *text= st->text; + Text *text; short xco, xmax; char naam[256]; - if (!st || st->spacetype != SPACE_TEXT) return; + if (st==NULL || st->spacetype != SPACE_TEXT) return; + + text = st->text; sprintf(naam, "header %d", curarea->headwin); block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin); From 9efe5e5b2327cf22bd187a3d17371f5d156ef9fa Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 23 Dec 2007 03:03:54 +0000 Subject: [PATCH 33/99] Fixed bug #7981, Crash with multires Caused by incorrect handling of multires with orco mapping --- .../blender/blenkernel/intern/DerivedMesh.c | 10 ++++++--- source/blender/blenkernel/intern/mesh.c | 21 ++++++------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index dd56fe2df61..9d51fc645ba 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2598,7 +2598,8 @@ float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl) } /* Propagate the changes to render level - fails if mesh topology changed */ -void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy, const int orig_lvl) +void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy, + const int orig_lvl, CustomDataMask dataMask) { if(me->mr) { if((*dm)->getNumVerts(*dm) == me->totvert && @@ -2619,6 +2620,9 @@ void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_c (*dm)= CDDM_copy(old); old->release(old); + if(dataMask & CD_MASK_ORCO) + add_orco_dm(ob, *dm, NULL); + /* Restore the original verts */ me->mr->newlvl= BLI_countlist(&me->mr->levels); multires_set_level(ob, me, 1); @@ -2646,7 +2650,7 @@ DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask) vert_copy= multires_render_pin(ob, me, &orig_lvl); mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask); - multires_render_final(ob, me, &final, vert_copy, orig_lvl); + multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask); return final; } @@ -2681,7 +2685,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, vert_copy= multires_render_pin(ob, me, &orig_lvl); mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask); - multires_render_final(ob, me, &final, vert_copy, orig_lvl); + multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask); return final; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 79a8afedf3f..56b1fe7e75b 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -489,21 +489,12 @@ float *get_mesh_orco_verts(Object *ob) vcos= mesh_getRefKeyCos(me, &totvert); } else { - MultiresLevel *lvl = NULL; - MVert *mvert = NULL; - - if(me->mr) { - lvl = multires_level_n(me->mr, me->mr->pinlvl); - vcos = MEM_callocN(sizeof(*vcos)*lvl->totvert, "orco mr mesh"); - mvert = me->mr->verts; - totvert = lvl->totvert; - } - else { - Mesh *tme = me->texcomesh?me->texcomesh:me; - vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh"); - mvert = tme->mvert; - totvert = MIN2(tme->totvert, me->totvert); - } + MVert *mvert = NULL; + Mesh *tme = me->texcomesh?me->texcomesh:me; + + vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh"); + mvert = tme->mvert; + totvert = MIN2(tme->totvert, me->totvert); for(a=0; aco[0]; From 74ebc7754729add77fa2b7dc9e74798a407bffed Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 23 Dec 2007 17:01:44 +0000 Subject: [PATCH 34/99] == Sequencer (Peach request) == Make the "Sync" button work when sound is disabled, Animators use this as a way to play animations at the right speed, could be renamed to "Drop Frames" and work even when blender built without audio enabled. (do not forget to give credit to me :) --- source/blender/src/drawview.c | 4 +--- source/blender/src/editscreen.c | 2 +- source/blender/src/seqaudio.c | 19 +++++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 5df1448ebc1..5568cc17231 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3274,8 +3274,7 @@ int update_time(void) static double ltime; double time; - if ((U.mixbufsize) - && (audiostream_pos() != CFRA) + if ((audiostream_pos() != CFRA) && (G.scene->audio.flag & AUDIO_SYNC)) { return 0; } @@ -3507,7 +3506,6 @@ void inner_play_anim_loop(int init, int mode) cached = cached_dynamics(PSFRA,PEFRA); } else { if (cached - && U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) { CFRA = audiostream_pos(); } else { diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index 741b6ab6d13..35c0692510d 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -1086,7 +1086,7 @@ int has_screenhandler(bScreen *sc, short eventcode) static void animated_screen(bScreen *sc, short val) { - if (U.mixbufsize && (val & TIME_WITH_SEQ_AUDIO)) { + if ((val & TIME_WITH_SEQ_AUDIO)) { if(CFRA>=PEFRA) { CFRA= PSFRA; audiostream_stop(); diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index de8cc488a85..b4d4f190f91 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -96,6 +96,7 @@ static int audio_scrub=0; static int audio_playing=0; static int audio_initialised=0; static int audio_startframe=0; +static double audio_starttime = 0.0; ///// // /* local protos ------------------- */ @@ -494,7 +495,7 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown) sound_init_audio(); } - if (!audio_initialised && !(duration + mixdown)) { + if (U.mixbufsize && !audio_initialised && !(duration + mixdown)) { desired.freq=G.scene->audio.mixrate; desired.format=AUDIO_S16SYS; desired.channels=2; @@ -508,7 +509,8 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown) audio_startframe = startframe; audio_pos = ( ((int)( FRA2TIME(startframe) *(G.scene->audio.mixrate)*4 )) & (~3) ); - + audio_starttime = PIL_check_seconds_timer(); + audio_scrub = duration; if (!mixdown) { SDL_PauseAudio(0); @@ -535,10 +537,15 @@ void audiostream_stop(void) int audiostream_pos(void) { int pos; - - pos = (int) (((double)(audio_pos-U.mixbufsize) - / ( G.scene->audio.mixrate*4 )) - * FPS ); + + if (U.mixbufsize) { + pos = (int) (((double)(audio_pos-U.mixbufsize) + / ( G.scene->audio.mixrate*4 )) + * FPS ); + } else { /* fallback to seconds_timer when no audio available */ + pos = (int) ((PIL_check_seconds_timer() - audio_starttime) + * FPS); + } if (pos < audio_startframe) pos = audio_startframe; return ( pos ); From 690d7a85bd7862ce01111335913bc22391049470 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 23 Dec 2007 17:27:06 +0000 Subject: [PATCH 35/99] == Playback (peach request) == Correct playback frames per second when "Play" is pressed. (Play spawns a new instance of blender, it could pass an argument that sets the frames per second) (double credit :) --- source/blender/src/buttons_scene.c | 4 ++-- source/blender/src/playanim.c | 16 ++++++++++++++++ source/creator/creator.c | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 7a4093dd965..8fd74ddc08e 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -507,9 +507,9 @@ static void run_playanim(char *file) calc_renderwin_rectangle((G.scene->r.xsch*G.scene->r.size)/100, (G.scene->r.ysch*G.scene->r.size)/100, G.winpos, pos, size); #ifdef WIN32 - sprintf(str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file); + sprintf(str, "%s -a -p %d %d -f %d %g \"%s\"", bprogname, pos[0], pos[1], G.scene->r.frs_sec, G.scene->r.frs_sec_base, file); #else - sprintf(str, "\"%s\" -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file); + sprintf(str, "\"%s\" -a -p %d %d -f %d %g \"%s\"", bprogname, pos[0], pos[1], G.scene->r.frs_sec, G.scene->r.frs_sec_base, file); #endif system(str); } diff --git a/source/blender/src/playanim.c b/source/blender/src/playanim.c index 828ff8e774e..e94366571db 100644 --- a/source/blender/src/playanim.c +++ b/source/blender/src/playanim.c @@ -362,6 +362,22 @@ void playanim(int argc, char **argv) printf("too few arguments for -p (need 2): skipping\n"); } break; + case 'f': + if (argc>3) { + double fps = atof(argv[2]); + double fps_base= atof(argv[3]); + if (fps == 0) { + fps = 1; + printf("invalid fps," + "forcing 1\n"); + } + swaptime = fps_base / fps; + argc-= 2; + argv+= 2; + } else { + printf("too few arguments for -f (need 2): skipping\n"); + } + break; default: printf("unknown option '%c': skipping\n", argv[1][1]); break; diff --git a/source/creator/creator.c b/source/creator/creator.c index 1feaf075e1c..6a780553607 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -194,6 +194,7 @@ static void print_help(void) printf (" -a \tPlayback \n"); printf (" -p \tOpen with lower left corner at , \n"); printf (" -m\t\tRead from disk (Don't buffer)\n"); + printf (" -f \t\tSpecify FPS to start with\n"); printf ("\nWindow options:\n"); printf (" -w\t\tForce opening with borders (default)\n"); From 6cbc3daf34c0d59383dfe01360608ffc5dee2fdf Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 23 Dec 2007 18:44:32 +0000 Subject: [PATCH 36/99] == FFMPEG == Fixes [#7475] no video as background libswscale sets the alpha channel to 0 by default... grmbl. Added a workaround. Big endian users please complain, if it doesn't work. --- source/blender/imbuf/intern/anim.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index e99c35e45ce..8a67c1d035f 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -720,6 +720,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { uint8_t* dst2[4]= { dst[0] + (anim->y - 1)*dstStride[0], 0, 0, 0 }; + int i; sws_scale(anim->img_convert_ctx, anim->pFrame->data, @@ -728,6 +729,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { anim->pCodecCtx->height, dst2, dstStride2); + + /* workaround: sws_scale sets alpha = 0... */ + for (i = 0; i < ibuf->x * ibuf->y; i++) { + ibuf->rect[i] |= 0xff000000; + } av_free_packet(&packet); break; From 9f7182b8c819279b74245ba4f0180a326ea26b2d Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 23 Dec 2007 19:21:43 +0000 Subject: [PATCH 37/99] == Sequencer == [#7861] Sequencer segfaults when trying to add images Fixed some _really_ stupid bugs in transform_seq, that made it segfault if one selected 0 images. --- source/blender/src/editseq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index bc453dd5a2e..c3264812c4b 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -2893,7 +2893,8 @@ void transform_seq(int mode, int context) TimeMarker *marker; /* looping on sequences, WHILE_SEQ macro allocates memory each time */ - int totseq_index, seq_index; Sequence **seqar; + int totseq_index, seq_index; + Sequence **seqar = 0; if(mode!='g' && mode!='e') return; /* from gesture */ @@ -2904,8 +2905,10 @@ void transform_seq(int mode, int context) /* Build the sequence array once, be sure to free it */ build_seqar( ed->seqbasep, &seqar, &totseq_index ); - for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) totstrip++; + if (seqar) { + for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { + if(seq->flag & SELECT) totstrip++; + } } if (sseq->flag & SEQ_MARKER_TRANS) { From 146b0aec14835872b2db9c18dc8615513050e6df Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 23 Dec 2007 21:27:12 +0000 Subject: [PATCH 38/99] == Sequencer == Fixed IPO calculation for threaded prefetch rendering. (do_seq_ipo used global CFRA tststs...) --- source/blender/blenkernel/BKE_ipo.h | 2 +- source/blender/blenkernel/intern/ipo.c | 9 ++++----- source/blender/src/seqaudio.c | 4 ++-- source/blender/src/sequence.c | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h index 2a6065eb4f1..01fe0903775 100644 --- a/source/blender/blenkernel/BKE_ipo.h +++ b/source/blender/blenkernel/BKE_ipo.h @@ -95,7 +95,7 @@ void do_ipo_nocalc(struct Ipo *ipo); void do_ipo(struct Ipo *ipo); void do_mat_ipo(struct Material *ma); void do_ob_ipo(struct Object *ob); -void do_seq_ipo(struct Sequence *seq); +void do_seq_ipo(struct Sequence *seq, int cfra); void do_ob_ipodrivers(struct Object *ob, struct Ipo *ipo, float ctime); int has_ipo_code(struct Ipo *ipo, int code); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 876f1c50a93..4af310913d6 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2161,7 +2161,7 @@ void do_ob_ipodrivers(Object *ob, Ipo *ipo, float ctime) } } -void do_seq_ipo(Sequence *seq) +void do_seq_ipo(Sequence *seq, int cfra) { float ctime, div; @@ -2169,11 +2169,10 @@ void do_seq_ipo(Sequence *seq) if(seq->ipo) { if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) { - ctime = frame_to_float(G.scene->r.cfra); + ctime = frame_to_float(cfra); div = 1.0; } else { - ctime= frame_to_float(G.scene->r.cfra - - seq->startdisp); + ctime= frame_to_float(cfra - seq->startdisp); div= (seq->enddisp - seq->startdisp)/100.0f; if(div==0.0) return; } @@ -2291,7 +2290,7 @@ void do_all_data_ipos() || seq->type == SEQ_HD_SOUND) && (seq->ipo) && (seq->startdisp<=G.scene->r.cfra+2) && (seq->enddisp>G.scene->r.cfra)) - do_seq_ipo(seq); + do_seq_ipo(seq, G.scene->r.cfra); seq= seq->next; } } diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index b4d4f190f91..ae76de90ddf 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -304,7 +304,7 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown, (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq); + do_seq_ipo(seq, CFRA); facf = seq->facf0; } else { facf = 1.0; @@ -333,7 +333,7 @@ static void audio_fill_hd_sound(Sequence *seq, (seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA)) { if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq); + do_seq_ipo(seq, CFRA); facf = seq->facf0; } else { facf = 1.0; diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 73eb0a96764..6d663b610ca 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -446,7 +446,7 @@ static void do_effect(int cfra, Sequence *seq, TStripElem *se) } if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq); + do_seq_ipo(seq, cfra); fac= seq->facf0; facf= seq->facf1; } else { @@ -962,7 +962,7 @@ static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) se->se3 = 0; if(seq->ipo && seq->ipo->curve.first) { - do_seq_ipo(seq); + do_seq_ipo(seq, cfra); fac= seq->facf0; facf= seq->facf1; } else { From 2b49858b0225e1b173c75b6c16c620542fcc2003 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 23 Dec 2007 23:41:16 +0000 Subject: [PATCH 39/99] Missing change in previous BPy revert. This was only the added build options in scons, so no harm done. --- tools/btools.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/btools.py b/tools/btools.py index 6ff0f401742..9f5a028f845 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -46,7 +46,6 @@ def validate_arguments(args, bc): 'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH', 'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'BF_OPENGL_LINKFLAGS', 'WITH_BF_FTGL', 'BF_FTGL', 'BF_FTGL_INC', 'BF_FTGL_LIB', - 'WITH_BF_BPYAPI_V24X', 'WITH_BF_PLAYER', 'CFLAGS', 'CCFLAGS', 'CPPFLAGS', 'REL_CFLAGS', 'REL_CCFLAGS', @@ -174,7 +173,6 @@ def read_opts(cfg, args): ('BF_FFMPEG_INC', 'FFMPEG includes', ''), ('BF_FFMPEG_LIBPATH', 'FFMPEG library path', ''), - (BoolOption('WITH_BF_BPYAPI_V24X', 'Compile Blender 2.4x python api if true', 'true')), (BoolOption('WITH_BF_JPEG', 'Use JPEG if true', 'true')), ('BF_JPEG', 'JPEG base path', ''), From df46987ba3936b9f3a13f221cfbfc60696fef2bc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Dec 2007 10:25:35 +0000 Subject: [PATCH 40/99] old bug in python api, Blender.Scene.Unlink() did not check if screens were using this scene or if it was used as a set elsewhere. In both cases this resulted in invalid pointers and crashes. Also was not freeing nodes or sequence data. --- source/blender/python/api2_2x/Scene.c | 27 ++++++++++++++++++++++++--- source/blender/src/header_info.c | 14 +++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 0875e43b4c7..397cee0ad5e 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -1,6 +1,6 @@ /* * - * $Id: Scene.c 12513 2007-11-07 18:52:23Z joeedh $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -51,12 +51,15 @@ struct View3D; #include "BLI_blenlib.h" /* only for SceneObSeq_new */ #include "BSE_drawview.h" /* for play_anim */ #include "BSE_headerbuttons.h" /* for copy_scene */ +#include "BSE_sequence.h" /* to clear_scene_in_allseqs */ +#include "BSE_node.h" /* to clear_scene_in_nodes */ #include "BIF_drawscene.h" /* for set_scene */ #include "BIF_space.h" /* for copy_view3d_lock() */ #include "BIF_screen.h" /* curarea */ #include "BDR_editobject.h" /* free_and_unlink_base() */ #include "mydevice.h" /* for #define REDRAW */ #include "DNA_view3d_types.h" + /* python types */ #include "Object.h" #include "Camera.h" @@ -718,8 +721,9 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args ) { PyObject *pyobj; BPy_Scene *pyscn; - Scene *scene; - + Scene *scene, *sce; + bScreen *sc; + if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, "expected Scene PyType object" ); @@ -733,6 +737,23 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args ) return EXPP_ReturnPyObjError( PyExc_SystemError, "current Scene cannot be removed!" ); + /* Copied from header_info.c */ + + /* check all sets */ + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if(sce->set == scene) sce->set= 0; + } + + /* check all sequences */ + clear_scene_in_allseqs(scene); + + /* check render layer nodes in other scenes */ + clear_scene_in_nodes(scene); + + for (sc= G.main->screen.first; sc; sc= sc->id.next ) { + if(sc->scene == scene) sc->scene= G.scene; + } + free_libblock( &G.main->scene, scene ); pyscn->scene= NULL; diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index fd7495dbbbe..174a5c683f0 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -484,18 +484,19 @@ void do_info_buttons(unsigned short event) else if(G.scene->id.next) sce= G.scene->id.next; else return; if(okee("Delete current scene")) { + /* Note, anything besides free_libblock needs to be added in + * Python Scene.c for Blender.Scene.Unlink() */ + /* exit modes... could become single call once */ exit_editmode(EM_FREEDATA|EM_WAITCURSOR); exit_paint_modes(); /* check all sets */ - sce1= G.main->scene.first; - while(sce1) { + for (sce1= G.main->scene.first; sce1; sce1= sce1->id.next) { if(sce1->set == G.scene) sce1->set= 0; - sce1= sce1->id.next; } - + /* check all sequences */ clear_scene_in_allseqs(G.scene); @@ -503,10 +504,9 @@ void do_info_buttons(unsigned short event) clear_scene_in_nodes(G.scene); /* al screens */ - sc= G.main->screen.first; - while(sc) { + + for (sc= G.main->screen.first; sc; sc= sc->id.next ) { if(sc->scene == G.scene) sc->scene= sce; - sc= sc->id.next; } free_libblock(&G.main->scene, G.scene); set_scene(sce); From 8a07e665c28a94ffd188daa431a4fd0c5a460eba Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Dec 2007 11:43:09 +0000 Subject: [PATCH 41/99] patch from Vladimir Espinosa for keying object layers from python --- source/blender/python/api2_2x/Object.c | 12 +++++++++--- source/blender/python/api2_2x/doc/Object.py | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index db8911cce2a..83c8ed7df3d 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -1,5 +1,5 @@ /* - * $Id: Object.c 12801 2007-12-05 21:50:23Z blendix $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -134,6 +134,7 @@ struct rctf; #define IPOKEY_PI_SURFACEDAMP 8 #define IPOKEY_PI_RANDOMDAMP 9 #define IPOKEY_PI_PERM 10 +#define IPOKEY_LAYER 19 #define PFIELD_FORCE 1 #define PFIELD_VORTEX 2 @@ -2343,7 +2344,7 @@ static int Object_setMatrix( BPy_Object * self, MatrixObject * mat ) /* * Object_insertIpoKey() - * inserts Object IPO key for LOC, ROT, SIZE, LOCROT, or LOCROTSIZE + * inserts Object IPO key for LOC, ROT, SIZE, LOCROT, LOCROTSIZE, or LAYER * Note it also inserts actions! */ @@ -2375,6 +2376,9 @@ static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args ) insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Y, 0); insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Z, 0); } + if (key == IPOKEY_LAYER ){ + insertkey((ID *)ob, ID_OB, actname, NULL,OB_LAY, 0); + } if (key == IPOKEY_PI_STRENGTH ){ insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FSTR, 0); @@ -5323,6 +5327,7 @@ static PyObject *M_Object_IpoKeyTypesDict( void ) PyConstant_Insert( d, "SIZE", PyInt_FromLong( IPOKEY_SIZE ) ); PyConstant_Insert( d, "LOCROT", PyInt_FromLong( IPOKEY_LOCROT ) ); PyConstant_Insert( d, "LOCROTSIZE", PyInt_FromLong( IPOKEY_LOCROTSIZE ) ); + PyConstant_Insert( d, "LAYER", PyInt_FromLong( IPOKEY_LAYER ) ); PyConstant_Insert( d, "PI_STRENGTH", PyInt_FromLong( IPOKEY_PI_STRENGTH ) ); PyConstant_Insert( d, "PI_FALLOFF", PyInt_FromLong( IPOKEY_PI_FALLOFF ) ); @@ -5360,7 +5365,8 @@ PyObject *Object_Init( void ) PyModule_AddIntConstant( module, "SIZE", IPOKEY_SIZE ); PyModule_AddIntConstant( module, "LOCROT", IPOKEY_LOCROT ); PyModule_AddIntConstant( module, "LOCROTSIZE", IPOKEY_LOCROTSIZE ); - + PyModule_AddIntConstant( module, "LAYER", IPOKEY_LAYER ); + PyModule_AddIntConstant( module, "PI_STRENGTH", IPOKEY_PI_STRENGTH ); PyModule_AddIntConstant( module, "PI_FALLOFF", IPOKEY_PI_FALLOFF ); PyModule_AddIntConstant( module, "PI_SURFACEDAMP", IPOKEY_PI_SURFACEDAMP ); diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 08ad7c68dca..4228f6de1a8 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -105,6 +105,7 @@ Example:: - SIZE - LOCROT - LOCROTSIZE + - LAYER - PI_STRENGTH - PI_FALLOFF - PI_SURFACEDAMP From 052a0551e49da2a1b07a42c3e67579d9ead4c1fe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Dec 2007 17:07:52 +0000 Subject: [PATCH 42/99] Added 'File->External Data->Make all files Absolute' OpenGL stamp also wasnt checking correctly (own error) --- source/blender/blenkernel/intern/image.c | 4 +- source/blender/blenlib/BLI_bpath.h | 1 + source/blender/blenlib/intern/bpath.c | 50 +++++++++++++++++++++--- source/blender/src/header_info.c | 18 +++++++-- source/blender/src/renderwin.c | 8 +++- 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ed944a3a4ea..dc8a020a189 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -812,8 +812,8 @@ static void stampdata(StampData *stamp_data, int do_prefix) } if (G.scene->r.stamp & R_STAMP_NOTE) { - if (do_prefix) sprintf(stamp_data->note, "Note %s", G.scene->r.stamp_udata); - else sprintf(stamp_data->note, "%s", G.scene->r.stamp_udata); + /* Never do prefix for Note */ + sprintf(stamp_data->note, "%s", G.scene->r.stamp_udata); } else { stamp_data->note[0] = '\0'; } diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index e2d7d23410c..32d20c4b13e 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -56,4 +56,5 @@ void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path /* creates a text file with missing files if there are any */ struct Text * checkMissingFiles(void); void makeFilesRelative(int *tot, int *changed, int *failed, int *linked); +void makeFilesAbsolute(int *tot, int *changed, int *failed, int *linked); void findMissingFiles(char *str); diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 2c1ebd59a55..2548c059064 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -347,15 +347,15 @@ void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { libpath = BLI_bpathIterator_getLib(&bpi); if(strncmp(filepath, "//", 2)) { - if (libpath) { /* cant make relative if we are kibrary - TODO, LOG THIS */ + if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */ (*linked)++; } else { /* local data, use the blend files path */ BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative)); BLI_makestringcode(G.sce, filepath_relative); - if (BLI_bpathIterator_getPathMaxLen(&bpi) < strlen(filepath_relative)) { + /* be safe and check the length */ + if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) { (*failed)++; } else { - /* safe to to check the length */ if(strncmp(filepath_relative, "//", 2)==0) { strcpy(filepath, filepath_relative); (*changed)++; @@ -365,12 +365,52 @@ void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { } } } - BLI_bpathIterator_step(&bpi); (*tot)++; } } +/* dont log any errors at the moment, should probably do this - + * Verry similar to makeFilesRelative - keep in sync! */ +void makeFilesAbsolute(int *tot, int *changed, int *failed, int *linked) { + struct BPathIterator bpi; + char *filepath, *libpath; + + /* be sure there is low chance of the path being too short */ + char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE]; + + *tot = *changed = *failed = *linked = 0; + + BLI_bpathIterator_init(&bpi); + while (!BLI_bpathIterator_isDone(&bpi)) { + filepath = BLI_bpathIterator_getPath(&bpi); + libpath = BLI_bpathIterator_getLib(&bpi); + + if(strncmp(filepath, "//", 2)==0) { + if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */ + (*linked)++; + } else { /* get the expanded path and check it is relative or too long */ + BLI_bpathIterator_copyPathExpanded( &bpi, filepath_absolute ); + + /* safe be safe, check the length */ + if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) { + (*failed)++; + } else { + if(strncmp(filepath_absolute, "//", 2)) { + strcpy(filepath, filepath_absolute); + (*changed)++; + } else { + (*failed)++; + } + } + } + } + BLI_bpathIterator_step(&bpi); + (*tot)++; + } +} + + /* find this file recursively, use the biggest file so thumbnails dont get used by mistake - dir: subdir to search - filename: set this filename @@ -387,8 +427,6 @@ static int findFileRecursive(char *filename_new, const char *dirname, const char char path[FILE_MAX]; int size; - printf("DIR %s\n", dirname); - dir = opendir(dirname); if (dir==0) diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 174a5c683f0..beb3eb52820 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -963,7 +963,16 @@ static void do_info_externalfiles(void *arg, int event) pupmenu("Can't set relative paths with an unsaved blend file"); } break; - case 11: /* check images exist */ + case 11: /* make all paths relative */ + { + int tot,changed,failed,linked; + char str[512]; + makeFilesAbsolute(&tot, &changed, &failed, &linked); + sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); + pupmenu(str); + } + break; + case 12: /* check images exist */ { /* Its really text but only care about the name */ ID *btxt = (ID *)checkMissingFiles(); @@ -977,7 +986,7 @@ static void do_info_externalfiles(void *arg, int event) } } break; - case 12: /* search for referenced files that are not available */ + case 13: /* search for referenced files that are not available */ activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles); break; } @@ -1002,8 +1011,9 @@ static uiBlock *info_externalfiles(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Absolute", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, ""); uiBlockSetDirection(block, UI_RIGHT); uiTextBoundsBlock(block, 60); diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index 8250ba4902d..e97fdef27ff 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -1300,7 +1300,9 @@ void BIF_do_ogl_render(View3D *v3d, int anim) do_ogl_view3d_render(re, v3d, winx, winy); glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32); - BKE_stamp_buf((unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty); + if((G.scene->r.scemode & R_STAMP_INFO) && (G.scene->r.stamp & R_STAMP_DRAW)) { + BKE_stamp_buf((unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty); + } window_swap_buffers(render_win->win); if(BKE_imtype_is_movie(G.scene->r.imtype)) { @@ -1340,7 +1342,9 @@ void BIF_do_ogl_render(View3D *v3d, int anim) else { do_ogl_view3d_render(re, v3d, winx, winy); glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32); - BKE_stamp_buf((unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty); + if((G.scene->r.scemode & R_STAMP_INFO) && (G.scene->r.stamp & R_STAMP_DRAW)) { + BKE_stamp_buf((unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty); + } window_swap_buffers(render_win->win); } From 9b45ead730328a37ab17c70c51d9d09bb39adcac Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 24 Dec 2007 17:35:54 +0000 Subject: [PATCH 43/99] == Skeletor == Commenting debug code that would output the harmonic weight to vertex color. --- source/blender/src/editarmature.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 8efa44213ed..45711bc1cfa 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -4704,14 +4704,14 @@ void generateSkeleton(void) error("No selected vertex\n"); return; } - - weightToHarmonic(em); renormalizeWeight(em, 1.0f); - -//#ifdef DEBUG_REEB + + weightToHarmonic(em); + +#ifdef DEBUG_REEB weightToVCol(em); -//#endif +#endif rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution); From 139cb3c0bc371bbc1740b6938bb61c9f80dbaadb Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 25 Dec 2007 06:48:45 +0000 Subject: [PATCH 44/99] =Scons ffmpeg update and avi fix= Updated scons to work with the ffmpeg binaries in lib/windows/gcc again. Also fixed a bug reported by Debolaz on irc. Blender's internal avi reading (which can only read simple formats like motion jpeg) was telling the video code it could read all avis, without checking their codec. To fix this, I copied AVI_open_movie(), and modified it to to replace AVI_is_avi(). Now it properly checks the codec, and validates the header. --- config/win32-mingw-config.py | 2 +- source/blender/avi/intern/avi.c | 190 ++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 1 deletion(-) diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 54d8e0c6ffd..8f8c30d46b0 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -18,7 +18,7 @@ BF_OPENAL_LIB = 'openal_static' BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' WITH_BF_FFMPEG = 'false' -BF_FFMPEG_LIB = 'avformat avutil avcodec' +BF_FFMPEG_LIB = 'xvidcore x264 avutil avformat avutil swscale avcodec avutil xvidcore x264' BF_FFMPEG_LIBPATH = LIBDIR + '/gcc/ffmpeg/lib' BF_FFMPEG_INC = LIBDIR + '/gcc/ffmpeg/include' diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 3ad844bfdc1..7e3d7ac6133 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -190,6 +190,7 @@ void AVI_set_debug (int mode) { AVI_DEBUG= mode; } +/* int AVI_is_avi (char *name) { FILE *fp; int ret; @@ -209,6 +210,195 @@ int AVI_is_avi (char *name) { fclose(fp); return ret; } +*/ + +int AVI_is_avi (char *name) { + int temp, fcca, j; + AviMovie movie; + AviMainHeader header; + AviBitmapInfoHeader bheader; + + DEBUG("opening movie\n"); + + memset(&movie, 0, sizeof(AviMovie)); + + movie.type = AVI_MOVIE_READ; + movie.fp = fopen (name, "rb"); + movie.offset_table = NULL; + + if (movie.fp == NULL) + return 0; + + if (GET_FCC (movie.fp) != FCC("RIFF") || + !(movie.size = GET_FCC (movie.fp))) { + fclose(movie.fp); + return 0; + } + + movie.header = &header; + + if (GET_FCC (movie.fp) != FCC("AVI ") || + GET_FCC (movie.fp) != FCC("LIST") || + !GET_FCC (movie.fp) || + GET_FCC (movie.fp) != FCC("hdrl") || + (movie.header->fcc = GET_FCC (movie.fp)) != FCC("avih") || + !(movie.header->size = GET_FCC (movie.fp))) { + DEBUG("bad initial header info\n"); + fclose(movie.fp); + return 0; + } + + movie.header->MicroSecPerFrame = GET_FCC(movie.fp); + movie.header->MaxBytesPerSec = GET_FCC(movie.fp); + movie.header->PaddingGranularity = GET_FCC(movie.fp); + movie.header->Flags = GET_FCC(movie.fp); + movie.header->TotalFrames = GET_FCC(movie.fp); + movie.header->InitialFrames = GET_FCC(movie.fp); + movie.header->Streams = GET_FCC(movie.fp); + movie.header->SuggestedBufferSize = GET_FCC(movie.fp); + movie.header->Width = GET_FCC(movie.fp); + movie.header->Height = GET_FCC(movie.fp); + movie.header->Reserved[0] = GET_FCC(movie.fp); + movie.header->Reserved[1] = GET_FCC(movie.fp); + movie.header->Reserved[2] = GET_FCC(movie.fp); + movie.header->Reserved[3] = GET_FCC(movie.fp); + + fseek (movie.fp, movie.header->size-14*4, SEEK_CUR); + + if (movie.header->Streams < 1) { + DEBUG("streams less than 1\n"); + fclose(movie.fp); + return 0; + } + + movie.streams = (AviStreamRec *) MEM_callocN (sizeof(AviStreamRec) * movie.header->Streams, "moviestreams"); + + for (temp=0; temp < movie.header->Streams; temp++) { + + if (GET_FCC(movie.fp) != FCC("LIST") || + !GET_FCC (movie.fp) || + GET_FCC (movie.fp) != FCC ("strl") || + (movie.streams[temp].sh.fcc = GET_FCC (movie.fp)) != FCC ("strh") || + !(movie.streams[temp].sh.size = GET_FCC (movie.fp))) { + DEBUG("bad stream header information\n"); + + MEM_freeN(movie.streams); + fclose(movie.fp); + return 0; + } + + movie.streams[temp].sh.Type = GET_FCC (movie.fp); + movie.streams[temp].sh.Handler = GET_FCC (movie.fp); + + fcca = movie.streams[temp].sh.Handler; + + if (movie.streams[temp].sh.Type == FCC("vids")) { + if (fcca == FCC ("DIB ") || + fcca == FCC ("RGB ") || + fcca == FCC ("rgb ") || + fcca == FCC ("RAW ") || + fcca == 0) { + movie.streams[temp].format = AVI_FORMAT_AVI_RGB; + } else if (fcca == FCC ("mjpg")||fcca == FCC ("MJPG")) { + movie.streams[temp].format = AVI_FORMAT_MJPEG; + } else { + MEM_freeN(movie.streams); + fclose(movie.fp); + return 0; + } + } + + movie.streams[temp].sh.Flags = GET_FCC (movie.fp); + movie.streams[temp].sh.Priority = GET_TCC (movie.fp); + movie.streams[temp].sh.Language = GET_TCC (movie.fp); + movie.streams[temp].sh.InitialFrames = GET_FCC (movie.fp); + movie.streams[temp].sh.Scale = GET_FCC (movie.fp); + movie.streams[temp].sh.Rate = GET_FCC (movie.fp); + movie.streams[temp].sh.Start = GET_FCC (movie.fp); + movie.streams[temp].sh.Length = GET_FCC (movie.fp); + movie.streams[temp].sh.SuggestedBufferSize = GET_FCC (movie.fp); + movie.streams[temp].sh.Quality = GET_FCC (movie.fp); + movie.streams[temp].sh.SampleSize = GET_FCC (movie.fp); + movie.streams[temp].sh.left = GET_TCC (movie.fp); + movie.streams[temp].sh.top = GET_TCC (movie.fp); + movie.streams[temp].sh.right = GET_TCC (movie.fp); + movie.streams[temp].sh.bottom = GET_TCC (movie.fp); + + fseek (movie.fp, movie.streams[temp].sh.size-14*4, SEEK_CUR); + + if (GET_FCC (movie.fp) != FCC("strf")) { + DEBUG("no stream format information\n"); + MEM_freeN(movie.streams); + fclose(movie.fp); + return 0; + } + + movie.streams[temp].sf_size= GET_FCC(movie.fp); + if (movie.streams[temp].sh.Type == FCC("vids")) { + j = movie.streams[temp].sf_size - (sizeof(AviBitmapInfoHeader) - 8); + if (j >= 0) { + AviBitmapInfoHeader *bi; + + movie.streams[temp].sf= &bheader; + bi= (AviBitmapInfoHeader *) movie.streams[temp].sf; + + bi->fcc= FCC("strf"); + bi->size= movie.streams[temp].sf_size; + bi->Size= GET_FCC(movie.fp); + bi->Width= GET_FCC(movie.fp); + bi->Height= GET_FCC(movie.fp); + bi->Planes= GET_TCC(movie.fp); + bi->BitCount= GET_TCC(movie.fp); + bi->Compression= GET_FCC(movie.fp); + bi->SizeImage= GET_FCC(movie.fp); + bi->XPelsPerMeter= GET_FCC(movie.fp); + bi->YPelsPerMeter= GET_FCC(movie.fp); + bi->ClrUsed= GET_FCC(movie.fp); + bi->ClrImportant= GET_FCC(movie.fp); + + fcca = bi->Compression; + + if ( movie.streams[temp].format == + AVI_FORMAT_AVI_RGB) { + if (fcca == FCC ("DIB ") || + fcca == FCC ("RGB ") || + fcca == FCC ("rgb ") || + fcca == FCC ("RAW ") || + fcca == 0 ) { + } else if ( fcca == FCC ("mjpg") || + fcca == FCC ("MJPG")) { + movie.streams[temp].format = AVI_FORMAT_MJPEG; + } else { + MEM_freeN(movie.streams); + fclose(movie.fp); + return 0; + } + } + + } + if (j > 0) fseek (movie.fp, j, SEEK_CUR); + } else fseek (movie.fp, movie.streams[temp].sf_size, SEEK_CUR); + + /* Walk to the next LIST */ + while (GET_FCC (movie.fp) != FCC("LIST")) { + temp= GET_FCC (movie.fp); + if (temp<0 || ftell(movie.fp) > movie.size) { + DEBUG("incorrect size in header or error in AVI\n"); + + MEM_freeN(movie.streams); + fclose(movie.fp); + return 0; + } + fseek(movie.fp, temp, SEEK_CUR); + } + + fseek(movie.fp, -4L, SEEK_CUR); + } + + MEM_freeN(movie.streams); + fclose(movie.fp); + return 1; +} AviError AVI_open_movie (char *name, AviMovie *movie) { int temp, fcca, size, j; From a3a88f9591683df6274e50249e350de5ba2dc7d6 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 25 Dec 2007 15:31:36 +0000 Subject: [PATCH 45/99] == Sequencer (includes a little bit of Peach :) == Reworked image / movie loading, to add the following features: - Mute strip - Lock strip (peach request :) - Crop / Translate _before_ image rescaling - N-keys editing of start, startofs, endofs, startstill, endstill Added (currently disabled) data structures for - proxy support - strip blend modes (currently only "REPLACE" works, which always did :) Planed: - automatic FPS rescaling - command keys to lock/mute a bunch of selected strips (which would complete the peach request to lock tracks) Caveats: now the N-keys dialog is four-tabbed. I think, we should move those tabs into the panels dialog in the future... --- source/blender/blenloader/intern/readfile.c | 18 + source/blender/blenloader/intern/writefile.c | 10 +- source/blender/makesdna/DNA_sequence_types.h | 39 +- source/blender/src/drawseq.c | 616 ++++++++++++++----- source/blender/src/editseq.c | 10 +- source/blender/src/sequence.c | 229 ++++--- 6 files changed, 662 insertions(+), 260 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 553ab0eb168..a90914e6dcb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3366,6 +3366,24 @@ static void direct_link_scene(FileData *fd, Scene *sce) } else { seq->strip->stripdata = 0; } + if (seq->flag & SEQ_USE_CROP) { + seq->strip->crop = newdataadr( + fd, seq->strip->crop); + } else { + seq->strip->crop = 0; + } + if (seq->flag & SEQ_USE_TRANSFORM) { + seq->strip->transform = newdataadr( + fd, seq->strip->transform); + } else { + seq->strip->transform = 0; + } + if (seq->flag & SEQ_USE_PROXY) { + seq->strip->proxy = newdataadr( + fd, seq->strip->proxy); + } else { + seq->strip->proxy = 0; + } } } END_SEQ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index d19c634e610..2e14fe55383 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1463,7 +1463,15 @@ static void write_scenes(WriteData *wd, ListBase *scebase) strip= seq->strip; writestruct(wd, DATA, "Strip", 1, strip); - + if(seq->flag & SEQ_USE_CROP && strip->crop) { + writestruct(wd, DATA, "StripCrop", 1, strip->crop); + } + if(seq->flag & SEQ_USE_TRANSFORM && strip->transform) { + writestruct(wd, DATA, "StripTransform", 1, strip->transform); + } + if(seq->flag & SEQ_USE_PROXY && strip->proxy) { + writestruct(wd, DATA, "StripProxy", 1, strip->proxy); + } if(seq->type==SEQ_IMAGE) writestruct(wd, DATA, "StripElem", strip->len, strip->stripdata); else if(seq->type==SEQ_MOVIE || seq->type==SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 0f9b55723bc..db3790e6ea3 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -56,12 +56,34 @@ typedef struct TStripElem { int nr; } TStripElem; +typedef struct StripCrop { + int top; + int bottom; + int left; + int right; +} StripCrop; + +typedef struct StripTransform { + int xofs; + int yofs; +} StripTransform; + +typedef struct StripProxy { + char dir[160]; + int format; + int width; + int height; +} StripProxy; + typedef struct Strip { struct Strip *next, *prev; int rt, len, us, done; StripElem *stripdata; char dir[160]; int orx, ory; + StripCrop *crop; + StripTransform *transform; + StripProxy *proxy; TStripElem *tstripdata; } Strip; @@ -96,7 +118,8 @@ typedef struct Sequence { void *lib; /* needed (to be like ipo), else it will raise libdata warnings, this should never be used */ char name[24]; /* name, not set by default and dosnt need to be unique as with ID's */ - short flag, type; /*flags bitmap (see below) and the type of sequence*/ + int flag, type; /*flags bitmap (see below) and the type of sequence*/ + int pad; int len; /* the length of the contense of this strip - before handles are applied */ int start, startofs, endofs; int startstill, endstill; @@ -129,7 +152,9 @@ typedef struct Sequence { void *effectdata; /* Struct pointer for effect settings */ int anim_preseek; - int pad; + int blend_mode; + float blend_opacity; + int pad2; } Sequence; typedef struct MetaStack { @@ -210,6 +235,12 @@ typedef struct SpeedControlVars { #define SEQ_FLAG_DELETE 1024 #define SEQ_FLIPX 2048 #define SEQ_FLIPY 4096 +#define SEQ_MAKE_FLOAT 8192 +#define SEQ_LOCK 16384 +#define SEQ_USE_PROXY 32768 +#define SEQ_USE_TRANSFORM 65536 +#define SEQ_USE_CROP 131072 + /* seq->type WATCH IT: SEQ_EFFECT BIT is used to determine if this is an effect strip!!! */ #define SEQ_IMAGE 0 @@ -240,5 +271,9 @@ typedef struct SpeedControlVars { #define STRIPELEM_OK 1 #define STRIPELEM_META 2 +#define SEQ_BLEND_REPLACE 0 +#define SEQ_BLEND_ALPHA_OVER 1 + + #endif diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 6213b669530..bcc47a7a1ca 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -1056,6 +1056,7 @@ void seq_viewmove(SpaceSeq *sseq) #define SEQ_BUT_RELOAD 2 #define SEQ_BUT_EFFECT 3 #define SEQ_BUT_RELOAD_ALL 4 +#define SEQ_BUT_TRANSFORM 5 void do_seqbuttons(short val) { @@ -1074,6 +1075,9 @@ void do_seqbuttons(short val) free_imbuf_seq(); // frees all + break; + case SEQ_BUT_TRANSFORM: + calc_sequence(last_seq); break; } @@ -1084,27 +1088,293 @@ void do_seqbuttons(short val) } } -static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES +#define SEQ_PANEL_EDITING 1 +#define SEQ_PANEL_INPUT 2 +#define SEQ_PANEL_FILTER 4 +#define SEQ_PANEL_EFFECT 8 +#define SEQ_PANEL_PROXY 16 + +static char* seq_panal_blend_modes() +{ + static char string[2048]; + char formatstring[2048]; + + strcpy(formatstring, "Blend mode: %%t|%s %%x%d|%s %%x%d"); + sprintf(string, formatstring, + "REPLACE", SEQ_BLEND_REPLACE, + "TODO: ALPHA OVER", SEQ_BLEND_ALPHA_OVER); + return string; + +} + +static void seq_panel_editing(short cntrl) +{ + Sequence *last_seq = get_last_seq(); + char * seq_names[] = { "Image", "Meta", "Scene", "Movie", + "Snd RAM", "Snd HD", + "", "Effect" }; + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing", + UI_EMBOSS, UI_HELV, curarea->win); + + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc + if(uiNewPanel(curarea, block, "Edit", "Seq", + 10, 230, 318, 204) == 0) return; + + uiDefBut(block, LABEL, + 0, (last_seq->type >= SEQ_EFFECT) ? + "Effect" : seq_names[last_seq->type], + 10,140,60,19, 0, + 0, 0, 0, 0, ""); + + uiDefBut(block, TEX, + B_NOP, "Name: ", + 70,140,180,19, last_seq->name+2, + 0.0, 21.0, 100, 0, ""); + + uiDefButI(block, MENU, SEQ_BUT_RELOAD, seq_panal_blend_modes(), + 10, 120, 120, 19, &last_seq->blend_mode, + 0,0,0,0, "Strip Blend Mode"); + + if (last_seq->blend_mode > 0) { + uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Blend:", + 130, 120, 120, 19, &last_seq->blend_opacity, + 0.0, 100.0, 100.0, 0, + "Blend opacity"); + } + + uiDefButBitI(block, TOG, SEQ_MUTE, + SEQ_BUT_RELOAD_ALL, "Mute", + 10,100,60,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Mute the current strip."); + + uiDefButBitI(block, TOG, SEQ_LOCK, + B_NOP, "Lock", + 70,100,60,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Lock strip, so that it can't be transformed."); + + uiDefButBitI(block, TOG, SEQ_IPO_FRAME_LOCKED, + SEQ_BUT_RELOAD_ALL, "IPO Frame locked", + 130,100,120,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Lock the IPO coordinates to the " + "global frame counter."); + + if (!(last_seq->flag & SEQ_LOCK)) { + uiDefButI(block, NUM, + SEQ_BUT_TRANSFORM, "Start", + 10, 80, 120, 20, &last_seq->start, + 0.0, MAXFRAMEF, 0.0, 0.0, "Start of strip"); + uiDefButI(block, NUM, + SEQ_BUT_TRANSFORM, "Chan", + 130, 80, 120, 20, &last_seq->machine, + 0.0, MAXSEQ, 0.0, 0.0, "Channel used (Y position)"); + + if (last_seq->type == SEQ_IMAGE) { + uiDefButI(block, NUM, + SEQ_BUT_TRANSFORM, "Start-Still", + 10, 60, 120, 20, &last_seq->startstill, + 0.0, MAXFRAMEF, 0.0, 0.0, "Start still"); + uiDefButI(block, NUM, + SEQ_BUT_TRANSFORM, "End-Still", + 130, 60, 120, 19, &last_seq->endstill, + 0.0, MAXFRAMEF, 0.0, 0.0, "End still"); + } else { + uiDefButI(block, NUM, + SEQ_BUT_TRANSFORM, "Start-Ofs", + 10, 60, 120, 20, &last_seq->startofs, + 0.0, last_seq->len, 0.0, 0.0, "Start offset"); + uiDefButI(block, NUM, + SEQ_BUT_TRANSFORM, "End-Ofs", + 130, 60, 120, 19, &last_seq->endofs, + 0.0, last_seq->len, 0.0, 0.0, "End offset"); + } + } +} + +static void seq_panel_input(short cntrl) { Sequence *last_seq = get_last_seq(); uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_input", + UI_EMBOSS, UI_HELV, curarea->win); - block= uiNewBlock(&curarea->uiblocks, "seq_panel_properties", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Edit", "Seq"); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Strip Properties", "Seq", 10, 230, 318, 204)==0) return; + if(uiNewPanel(curarea, block, "Input", "Seq", + 10, 230, 318, 204) == 0) return; - if(last_seq==NULL) return; + + uiDefButBitI(block, TOG, SEQ_USE_CROP, + SEQ_BUT_RELOAD, "Use Crop", + 10,100,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Crop image before processing."); - if(last_seq->type==SEQ_PLUGIN) { + if (last_seq->flag & SEQ_USE_CROP) { + if (!last_seq->strip->crop) { + last_seq->strip->crop = + MEM_callocN(sizeof(struct StripCrop), + "StripCrop"); + } + uiDefButI(block, NUM, + SEQ_BUT_RELOAD, "Top", + 10, 80, 120, 20, &last_seq->strip->crop->top, + 0.0, 4096, 0.0, 0.0, "Top of source image"); + uiDefButI(block, NUM, + SEQ_BUT_RELOAD, "Bottom", + 130, 80, 120, 20, &last_seq->strip->crop->bottom, + 0.0, 4096, 0.0, 0.0, "Bottom of source image"); + + uiDefButI(block, NUM, + SEQ_BUT_RELOAD, "Left", + 10, 60, 120, 20, &last_seq->strip->crop->left, + 0.0, 4096, 0.0, 0.0, "Left"); + uiDefButI(block, NUM, + SEQ_BUT_RELOAD, "Right", + 130, 60, 120, 19, &last_seq->strip->crop->right, + 0.0, 4096, 0.0, 0.0, "Right"); + } + + uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, + SEQ_BUT_RELOAD, "Use Translate", + 10,40,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Translate image before processing."); + + if (last_seq->flag & SEQ_USE_TRANSFORM) { + if (!last_seq->strip->transform) { + last_seq->strip->transform = + MEM_callocN(sizeof(struct StripTransform), + "StripTransform"); + } + uiDefButI(block, NUM, + SEQ_BUT_RELOAD, "X-Ofs", + 10, 20, 120, 20, &last_seq->strip->transform->xofs, + 0.0, 4096, 0.0, 0.0, "X Offset"); + uiDefButI(block, NUM, + SEQ_BUT_RELOAD, "Y-Ofs", + 130, 20, 120, 20, &last_seq->strip->transform->yofs, + 0.0, 4096, 0.0, 0.0, "Y Offset"); + } + + + uiDefButI(block, NUM, SEQ_BUT_RELOAD, "Preseek:", + 10,0,150,19, &last_seq->anim_preseek, + 0.0, 50.0, 100,0,"On MPEG-seeking preseek this many frames"); + +} + +static void seq_panel_filter_video(short cntrl) +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter", + UI_EMBOSS, UI_HELV, curarea->win); + + uiNewPanelTabbed("Edit", "Seq"); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc + if(uiNewPanel(curarea, block, "Filter", "Seq", + 10, 230, 318, 204) == 0) return; + + + uiBlockBeginAlign(block); + + + uiDefButBitI(block, TOG, SEQ_MAKE_PREMUL, + SEQ_BUT_RELOAD, "Convert to Premul", + 10,110,150,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Converts RGB values to become premultiplied with Alpha"); + + uiDefButBitI(block, TOG, SEQ_FILTERY, + SEQ_BUT_RELOAD, "FilterY", + 10,90,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "For video movies to remove fields"); + + uiDefButBitI(block, TOG, SEQ_MAKE_FLOAT, + SEQ_BUT_RELOAD, "Make Float", + 85,90,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Convert input to float data"); + + uiDefButBitI(block, TOG, SEQ_FLIPX, + SEQ_BUT_RELOAD, "FlipX", + 10,70,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Flip on the X axis"); + uiDefButBitI(block, TOG, SEQ_FLIPY, + SEQ_BUT_RELOAD, "FlipY", + 85,70,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Flip on the Y axis"); + + uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:", + 10,50,150,19, &last_seq->mul, + 0.001, 5.0, 100, 0, + "Multiply colors"); + + uiDefButBitI(block, TOG, SEQ_REVERSE_FRAMES, + SEQ_BUT_RELOAD, "Reverse Frames", + 10,30,150,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Reverse frame order"); + + uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:", + 10,10,150,19, &last_seq->strobe, + 1.0, 30.0, 100, 0, + "Only display every nth frame"); + + uiBlockEndAlign(block); + +} + + +static void seq_panel_filter_audio(short cntrl) +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter", + UI_EMBOSS, UI_HELV, curarea->win); + + uiNewPanelTabbed("Edit", "Seq"); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc + if(uiNewPanel(curarea, block, "Filter", "Seq", + 10, 230, 318, 204) == 0) return; + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, ""); + uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:", 10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, ""); + uiBlockEndAlign(block); +} + +static void seq_panel_effect(short cntrl) +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_effect", + UI_EMBOSS, UI_HELV, curarea->win); + + uiNewPanelTabbed("Edit", "Seq"); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc + if(uiNewPanel(curarea, block, "Effect", "Seq", + 10, 230, 318, 204) == 0) return; + + if(last_seq->type == SEQ_PLUGIN) { PluginSeq *pis; VarStruct *varstr; int a, xco, yco; get_sequence_effect(last_seq);/* make sure, plugin is loaded */ - uiDefBut(block, LABEL, 0, "Type: Plugin", 10,50,70,20, 0, 0, 0, 0, 0, ""); - pis= last_seq->plugin; if(pis->vars==0) return; @@ -1117,184 +1387,192 @@ static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES } } - uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED, - SEQ_BUT_RELOAD_ALL, "IPO Frame locked", - 10,-40,150,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Lock the IPO coordinates to the " - "global frame counter."); + return; + } + uiBlockBeginAlign(block); + + if(last_seq->type==SEQ_WIPE){ + WipeVars *wipe = (WipeVars *)last_seq->effectdata; + char formatstring[256]; + + strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255); + uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring, 10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed"); + uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Blur:", 10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge"); + switch(wipe->wipetype){ /*Skip Types that do not require angle*/ + case DO_IRIS_WIPE: + case DO_CLOCK_WIPE: + break; + + default: + uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:", 10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge"); + } + uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In", 10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe"); + } else if(last_seq->type==SEQ_GLOW){ + GlowVars *glow = (GlowVars *)last_seq->effectdata; + + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:", 10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:", 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:", 10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:", 10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect"); + uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect"); + uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only"); } - else if(last_seq->type==SEQ_IMAGE) { + else if(last_seq->type==SEQ_TRANSFORM){ + TransformVars *transform = (TransformVars *)last_seq->effectdata; - uiDefBut(block, LABEL, 0, "Type: Image", 10,160,150,20, 0, 0, 0, 0, 0, ""); - uiDefBut(block, TEX, B_NOP, "Name: ", 10,140,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, ""); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale Start:", 10,70,150,19, &transform->ScalexIni, 0.0, 10.0, 0, 0, "X Scale Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale End:", 160,70,150,19, &transform->ScalexFin, 0.0, 10.0, 0, 0, "X Scale End"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale Start:", 10,50,150,19, &transform->ScaleyIni, 0.0, 10.0, 0, 0, "Y Scale Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale End:", 160,50,150,19, &transform->ScaleyFin, 0.0, 10.0, 0, 0, "Y Scale End"); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Convert to Premul", 10,110,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha"); - uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields"); + uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Percent", 10, 30, 150, 19, &transform->percent, 0.0, 1.0, 0.0, 0.0, "Percent Translate"); + uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Pixels", 160, 30, 150, 19, &transform->percent, 0.0, 0.0, 0.0, 0.0, "Pixels Translate"); + if(transform->percent==1){ + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -500.0, 500.0, 0, 0, "X Position Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -500.0, 500.0, 0, 0, "X Position End"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -500.0, 500.0, 0, 0, "Y Position Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -500.0, 500.0, 0, 0, "Y Position End"); + } else { + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -10000.0, 10000.0, 0, 0, "X Position Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -10000.0, 10000.0, 0, 0, "X Position End"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -10000.0, 10000.0, 0, 0, "Y Position Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -10000.0, 10000.0, 0, 0, "Y Position End"); + + } - uiDefButBitS(block, TOG, SEQ_FLIPX, SEQ_BUT_RELOAD, "FlipX", 10,70,75,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Flip on the X axis"); - uiDefButBitS(block, TOG, SEQ_FLIPY, SEQ_BUT_RELOAD, "FlipY", 85,70,75,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Flip on the Y axis"); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:", 10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors"); - uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order"); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:", 10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame"); - uiBlockEndAlign(block); - } - else if(last_seq->type==SEQ_META) { - - uiDefBut(block, LABEL, 0, "Type: Meta", 10,140,150,20, 0, 0, 0, 0, 0, ""); - uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, ""); - - } - else if(last_seq->type==SEQ_SCENE) { - - uiDefBut(block, LABEL, 0, "Type: Scene", 10,140,150,20, 0, 0, 0, 0, 0, ""); - uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, ""); - uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order"); - } - else if(last_seq->type==SEQ_MOVIE) { - - if(last_seq->mul==0.0) last_seq->mul= 1.0; - - uiDefBut(block, LABEL, 0, "Type: Movie", 10,140,150,20, 0, 0, 0, 0, 0, ""); - uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, ""); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Make Premul Alpha ", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha"); - uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY ", 10,70,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields"); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:", 10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot Start:",10,-30,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start"); + uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot End:",160,-30,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End"); - uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order"); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:", 10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame"); - uiDefButI(block, NUM, SEQ_BUT_RELOAD, "Preseek:", 10,-10,150,19, &last_seq->anim_preseek, 0.0, 50.0, 100, 0, "On MPEG-seeking preseek this many frames"); - uiBlockEndAlign(block); - } - else if(last_seq->type==SEQ_RAM_SOUND || - last_seq->type==SEQ_HD_SOUND) { - - uiDefBut(block, LABEL, 0, "Type: Audio", 10,140,150,20, 0, 0, 0, 0, 0, ""); - uiDefBut(block, TEX, 0, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, ""); + uiDefButI(block, ROW, SEQ_BUT_EFFECT, "No Interpolat", 10, -50, 100, 19, &transform->interpolation, 0.0, 0.0, 0.0, 0.0, "No interpolation"); + uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Bilinear", 101, -50, 100, 19, &transform->interpolation, 0.0, 1.0, 0.0, 0.0, "Bilinear interpolation"); + uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Bicubic", 202, -50, 100, 19, &transform->interpolation, 0.0, 2.0, 0.0, 0.0, "Bicubic interpolation"); + } else if(last_seq->type==SEQ_COLOR) { + SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata; + uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, ""); + } else if(last_seq->type==SEQ_SPEED){ + SpeedControlVars *sp = + (SpeedControlVars *)last_seq->effectdata; - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED, - SEQ_BUT_RELOAD_ALL, "IPO Frame locked", - 10,90,150,19, &last_seq->flag, + uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed"); + + uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE, + SEQ_BUT_RELOAD, + "IPO is velocity", + 10,50,150,19, &sp->flags, 0.0, 1.0, 0, 0, - "Lock the IPO coordinates to the " - "global frame counter."); + "Interpret the IPO value as a " + "velocity instead of a frame number"); - uiDefButBitS(block, TOG, SEQ_MUTE, B_NOP, "Mute", 10,70,120,19, &last_seq->flag, 0.0, 21.0, 100, 0, ""); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, ""); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:", 10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, ""); - uiBlockEndAlign(block); - } - else if(last_seq->type>=SEQ_EFFECT) { - uiDefBut(block, LABEL, 0, "Type: Effect", 10,140,150,20, 0, 0, 0, 0, 0, ""); - uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, ""); - - uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED, - SEQ_BUT_RELOAD_ALL, "IPO Frame locked", - 10,90,150,19, &last_seq->flag, + uiDefButBitI(block, TOG, SEQ_SPEED_BLEND, + SEQ_BUT_RELOAD, + "Enable frame blending", + 10,30,150,19, &sp->flags, 0.0, 1.0, 0, 0, - "Lock the IPO coordinates to the " - "global frame counter."); + "Blend two frames into the " + "target for a smoother result"); - uiBlockBeginAlign(block); - if(last_seq->type==SEQ_WIPE){ - WipeVars *wipe = (WipeVars *)last_seq->effectdata; - char formatstring[256]; - - strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255); - uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring, 10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed"); - uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Blur:", 10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge"); - switch(wipe->wipetype){ /*Skip Types that do not require angle*/ - case DO_IRIS_WIPE: - case DO_CLOCK_WIPE: - break; - - default: - uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:", 10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge"); - } - uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In", 10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe"); + uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y, + SEQ_BUT_RELOAD, + "IPO value runs from [0..1]", + 10,10,150,19, &sp->flags, + 0.0, 1.0, 0, 0, + "Scale IPO value to get the " + "target frame number."); + } + + uiBlockEndAlign(block); +} + +static void seq_panel_proxy(short cntrl) +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_proxy", + UI_EMBOSS, UI_HELV, curarea->win); + + uiNewPanelTabbed("Edit", "Seq"); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc + if(uiNewPanel(curarea, block, "Proxy", "Seq", + 10, 230, 318, 204) == 0) return; + + uiBlockBeginAlign(block); + + uiDefButBitI(block, TOG, SEQ_USE_PROXY, + SEQ_BUT_RELOAD, "Use Proxy", + 10,140,150,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Use a preview proxy for this strip"); + + if (last_seq->flag & SEQ_USE_PROXY) { + + + } + + uiBlockEndAlign(block); +} + + +static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES +{ + Sequence *last_seq = get_last_seq(); + int panels = 0; + int type; + + if(last_seq == NULL) { + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing", + UI_EMBOSS, UI_HELV, curarea->win); + + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); + uiNewPanel(curarea, block, "Edit", "Seq", + 10, 230, 318, 204); + return; + } + + type = last_seq->type; + + panels = SEQ_PANEL_EDITING; + + if (type == SEQ_MOVIE || type == SEQ_IMAGE || type == SEQ_SCENE + || type == SEQ_HD_SOUND) { + panels |= SEQ_PANEL_INPUT | SEQ_PANEL_FILTER | SEQ_PANEL_PROXY; + } + + if (type == SEQ_RAM_SOUND) { + panels |= SEQ_PANEL_FILTER; + } + + if (type == SEQ_PLUGIN || type >= SEQ_EFFECT) { + panels |= SEQ_PANEL_EFFECT | SEQ_PANEL_PROXY; + } + + if (panels & SEQ_PANEL_EDITING) { + seq_panel_editing(cntrl); + } + + if (panels & SEQ_PANEL_INPUT) { + seq_panel_input(cntrl); + } + + if (panels & SEQ_PANEL_FILTER) { + if (type == SEQ_RAM_SOUND || type == SEQ_HD_SOUND) { + seq_panel_filter_audio(cntrl); + } else { + seq_panel_filter_video(cntrl); } - else if(last_seq->type==SEQ_GLOW){ - GlowVars *glow = (GlowVars *)last_seq->effectdata; + } - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:", 10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:", 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:", 10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:", 10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect"); - uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect"); - uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only"); - } - else if(last_seq->type==SEQ_TRANSFORM){ - TransformVars *transform = (TransformVars *)last_seq->effectdata; + if (panels & SEQ_PANEL_EFFECT) { + seq_panel_effect(cntrl); + } - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale Start:", 10,70,150,19, &transform->ScalexIni, 0.0, 10.0, 0, 0, "X Scale Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale End:", 160,70,150,19, &transform->ScalexFin, 0.0, 10.0, 0, 0, "X Scale End"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale Start:", 10,50,150,19, &transform->ScaleyIni, 0.0, 10.0, 0, 0, "Y Scale Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale End:", 160,50,150,19, &transform->ScaleyFin, 0.0, 10.0, 0, 0, "Y Scale End"); - - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Percent", 10, 30, 150, 19, &transform->percent, 0.0, 1.0, 0.0, 0.0, "Percent Translate"); - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Pixels", 160, 30, 150, 19, &transform->percent, 0.0, 0.0, 0.0, 0.0, "Pixels Translate"); - if(transform->percent==1){ - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -500.0, 500.0, 0, 0, "X Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -500.0, 500.0, 0, 0, "X Position End"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -500.0, 500.0, 0, 0, "Y Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -500.0, 500.0, 0, 0, "Y Position End"); - }else{ - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -10000.0, 10000.0, 0, 0, "X Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -10000.0, 10000.0, 0, 0, "X Position End"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -10000.0, 10000.0, 0, 0, "Y Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -10000.0, 10000.0, 0, 0, "Y Position End"); - - } - - - - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot Start:",10,-30,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot End:",160,-30,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End"); - - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "No Interpolat", 10, -50, 100, 19, &transform->interpolation, 0.0, 0.0, 0.0, 0.0, "No interpolation"); - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Bilinear", 101, -50, 100, 19, &transform->interpolation, 0.0, 1.0, 0.0, 0.0, "Bilinear interpolation"); - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Bicubic", 202, -50, 100, 19, &transform->interpolation, 0.0, 2.0, 0.0, 0.0, "Bicubic interpolation"); - } else if(last_seq->type==SEQ_COLOR) { - SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata; - uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, ""); - } else if(last_seq->type==SEQ_SPEED){ - SpeedControlVars *sp = - (SpeedControlVars *)last_seq->effectdata; - - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed"); - - uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE, - SEQ_BUT_RELOAD, - "IPO is velocity", - 10,50,150,19, &sp->flags, - 0.0, 1.0, 0, 0, - "Interpret the IPO value as a " - "velocity instead of a frame number"); - - uiDefButBitI(block, TOG, SEQ_SPEED_BLEND, - SEQ_BUT_RELOAD, - "Enable frame blending", - 10,30,150,19, &sp->flags, - 0.0, 1.0, 0, 0, - "Blend two frames into the " - "target for a smoother result"); - - uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y, - SEQ_BUT_RELOAD, - "IPO value runs from [0..1]", - 10,10,150,19, &sp->flags, - 0.0, 1.0, 0, 0, - "Scale IPO value to get the " - "target frame number."); - } - - uiBlockEndAlign(block); + if (panels & SEQ_PANEL_PROXY) { + seq_panel_proxy(cntrl); } } diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index c3264812c4b..8b3b2dd6082 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -2907,7 +2907,8 @@ void transform_seq(int mode, int context) if (seqar) { for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) totstrip++; + if((seq->flag & SELECT) && !(seq->flag & SEQ_LOCK)) + totstrip++; } } @@ -2929,7 +2930,7 @@ void transform_seq(int mode, int context) ts=transmain= MEM_callocN(totstrip*sizeof(TransSeq), "transseq"); for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) { + if((seq->flag & SELECT) && !(seq->flag & SEQ_LOCK)) { ts->start= seq->start; ts->machine= seq->machine; ts->startstill= seq->startstill; @@ -3612,7 +3613,8 @@ void seq_snap(short event) /* also check metas */ WHILE_SEQ(ed->seqbasep) { - if (seq->flag & SELECT && sequence_is_free_transformable(seq)) { + if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK) && + sequence_is_free_transformable(seq)) { if((seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0) { seq->start= CFRA-seq->startofs+seq->startstill; } else { @@ -3630,7 +3632,7 @@ void seq_snap(short event) /* test for effects and overlap */ WHILE_SEQ(ed->seqbasep) { - if(seq->flag & SELECT) { + if(seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { seq->flag &= ~SEQ_OVERLAP; if( test_overlap_seq(seq) ) { shuffle_seq(seq); diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 6d663b610ca..9a94f16712c 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -97,6 +97,11 @@ void free_tstripdata(int len, TStripElem *se) } +void seq_proxy_free(StripProxy * proxy) +{ + MEM_freeN(proxy); +} + void free_strip(Strip *strip) { strip->us--; @@ -109,6 +114,15 @@ void free_strip(Strip *strip) if(strip->stripdata) { MEM_freeN(strip->stripdata); } + if (strip->crop) { + MEM_freeN(strip->crop); + } + if (strip->transform) { + MEM_freeN(strip->transform); + } + if (strip->proxy) { + seq_proxy_free(strip->proxy); + } free_tstripdata(strip->len, strip->tstripdata); @@ -672,7 +686,9 @@ Sequence *get_shown_sequence(ListBase * seqbasep, int cfra, int chanshown) for(b=1; btype & SEQ_EFFECT) { + if(seq->flag & SEQ_MUTE) { + /* skip */ + } else if(seq->type & SEQ_EFFECT) { if(seqeff==0) seqeff= seq; else if(seqeff->machine < seq->machine) seqeff= seq; @@ -726,12 +742,134 @@ void set_meta_stripdata(Sequence *seqm) } } +/* + input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE + + Do all the things you can't really do afterwards using sequence effects + (read: before rescaling to render resolution has been done) + + Order is important! + + - Deinterlace + - Crop and transform in image source coordinate space + - Flip X + Flip Y (could be done afterwards, backward compatibility) + - Promote image to float data (affects pipeline operations afterwards) + - Premultiply + +*/ + +static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) +{ + seq->strip->orx= se->ibuf->x; + seq->strip->ory= se->ibuf->y; + + if(seq->flag & SEQ_FILTERY) { + IMB_filtery(se->ibuf); + } + + if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) { + StripCrop c; + StripTransform t; + + memset(&c, 0, sizeof(StripCrop)); + memset(&t, 0, sizeof(StripTransform)); + + if(seq->flag & SEQ_USE_CROP && seq->strip->crop) { + c = *seq->strip->crop; + } + if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) { + t = *seq->strip->transform; + } + + if (c.top + c.bottom >= se->ibuf->y || + c.left + c.right >= se->ibuf->x || + t.xofs >= se->ibuf->x || + t.yofs >= se->ibuf->y) { + make_black_ibuf(se->ibuf); + } else { + ImBuf * i; + int sx = se->ibuf->x - c.left - c.right; + int sy = se->ibuf->y - c.top - c.bottom; + int dx = sx; + int dy = sy; + + if (seq->flag & SEQ_USE_TRANSFORM) { + dx = seqrectx; + dy = seqrecty; + } + + if (se->ibuf->rect_float) { + i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0); + } else { + i = IMB_allocImBuf(dx, dy,32, IB_rect, 0); + } + + IMB_rectcpy(i, se->ibuf, + t.xofs, t.yofs, + c.left, c.bottom, + sx, sy); + + IMB_freeImBuf(se->ibuf); + + se->ibuf = i; + } + } + + if(seq->flag & SEQ_FLIPX) { + IMB_flipx(se->ibuf); + } + if(seq->flag & SEQ_FLIPY) { + IMB_flipy(se->ibuf); + } + + if(seq->flag & SEQ_MAKE_FLOAT) { + if (!se->ibuf->rect_float) { + IMB_float_from_rect(se->ibuf); + } + } + + if(seq->mul == 0.0) { + seq->mul = 1.0; + } + if(seq->mul != 1.0) { + multibuf(se->ibuf, seq->mul); + } + + if(seq->flag & SEQ_MAKE_PREMUL) { + if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) { + converttopremul(se->ibuf); + } + } + + + if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { + if(G.scene->r.mode & R_OSA) { + IMB_scaleImBuf(se->ibuf, + (short)seqrectx, (short)seqrecty); + } else { + IMB_scalefastImBuf(se->ibuf, + (short)seqrectx, (short)seqrecty); + } + } +} + static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra); static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) { char name[FILE_MAXDIR+FILE_MAXFILE]; + if (seq->type != SEQ_META && se->ibuf) { + /* test if image too small + or discarded from cache: reload */ + if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty + || !(se->ibuf->rect || se->ibuf->rect_float)) { + IMB_freeImBuf(se->ibuf); + se->ibuf= 0; + se->ok= STRIPELEM_OK; + } + } + if(seq->type == SEQ_META) { if(seq->seqbase.first) { Sequence * seqmshown= @@ -751,15 +889,6 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) se->ibuf= se->se1->ibuf; } } else if(seq->type & SEQ_EFFECT) { - - /* test if image is too small or discarded from cache: reload */ - if(se->ibuf) { - if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - } - } - /* should the effect be recalculated? */ if(se->ibuf == 0) { @@ -772,58 +901,22 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) do_effect(cfra, seq, se); } - - /* test size */ - if(se->ibuf) { - if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { - if(G.scene->r.mode & R_OSA) { - IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); - } else { - IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); - } - } - } + } else if(seq->type < SEQ_EFFECT) { - if(se->ibuf) { - /* test if image too small - or discarded from cache: reload */ - if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - se->ok= STRIPELEM_OK; - } - } if(seq->type==SEQ_IMAGE) { if(se->ok == STRIPELEM_OK && se->ibuf==0) { StripElem * s_elem = give_stripelem(seq, cfra); - /* if playanim or render: - no waitcursor */ - if((G.f & G_PLAYANIM)==0) - waitcursor(1); - strncpy(name, seq->strip->dir, FILE_MAXDIR-1); strncat(name, s_elem->name, FILE_MAXFILE); BLI_convertstringcode(name, G.sce, G.scene->r.cfra); se->ibuf= IMB_loadiffname(name, IB_rect); - if((G.f & G_PLAYANIM)==0) - waitcursor(0); - if(se->ibuf == 0) { se->ok = STRIPELEM_FAILED; } else { - if(seq->flag & SEQ_MAKE_PREMUL) { - if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf); - } - seq->strip->orx= se->ibuf->x; - seq->strip->ory= se->ibuf->y; - if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf); - if(seq->flag & SEQ_FLIPX) IMB_flipx(se->ibuf); - if(seq->flag & SEQ_FLIPY) IMB_flipy(se->ibuf); - if(seq->mul==0.0) seq->mul= 1.0; - if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul); + input_preprocess(seq, se, cfra); } } } @@ -844,14 +937,7 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) if(se->ibuf == 0) { se->ok = STRIPELEM_FAILED; } else { - if(seq->flag & SEQ_MAKE_PREMUL) { - if(se->ibuf->depth==32) converttopremul(se->ibuf); - } - seq->strip->orx= se->ibuf->x; - seq->strip->ory= se->ibuf->y; - if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf); - if(seq->mul==0.0) seq->mul= 1.0; - if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul); + input_preprocess(seq, se, cfra); } } } else if(seq->type==SEQ_SCENE && se->ibuf==NULL && seq->scene) { // scene can be NULL after deletions @@ -915,34 +1001,9 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */ waitcursor(0); CFRA = oldcfra; - } - - /* size test */ - if(se->ibuf) { - if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { - - if (0) { // G.scene->r.mode & R_FIELDS) { - - if (seqrecty > 288) - IMB_scalefieldImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); - else { - IMB_de_interlace(se->ibuf); - - if(G.scene->r.mode & R_OSA) - IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); - else - IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); - } - } - else { - if(G.scene->r.mode & R_OSA) - IMB_scaleImBuf(se->ibuf,(short)seqrectx, (short)seqrecty); - else - IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); - } - } - - } + + input_preprocess(seq, se, cfra); + } } if (se->ibuf && seq->type != SEQ_META) { IMB_cache_limiter_insert(se->ibuf); From 6e812d5901bac112de3168ec530c42681216f6ec Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 25 Dec 2007 20:31:07 +0000 Subject: [PATCH 46/99] == Sequencer == * Make Lock flag work for metastrips * Fixes: flags are cleared on exit of metastrips * Fixes (hopefully): red picture on big endian --- source/blender/imbuf/intern/anim.c | 7 +++- source/blender/include/BSE_sequence.h | 7 ++++ source/blender/src/editseq.c | 36 +++++++++++----- source/blender/src/sequence.c | 60 +++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 11 deletions(-) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 8a67c1d035f..e72d535815e 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -721,6 +721,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { dst[0] + (anim->y - 1)*dstStride[0], 0, 0, 0 }; int i; + unsigned char* r; sws_scale(anim->img_convert_ctx, anim->pFrame->data, @@ -731,8 +732,12 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { dstStride2); /* workaround: sws_scale sets alpha = 0... */ + + r = (unsigned char*) ibuf->rect; + for (i = 0; i < ibuf->x * ibuf->y; i++) { - ibuf->rect[i] |= 0xff000000; + r[3] = 0xff; + r+=4; } av_free_packet(&packet); diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index fdf584b38f4..7bdf16e8e90 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -50,6 +50,13 @@ void free_strip(struct Strip *strip); void new_tstripdata(struct Sequence *seq); void free_sequence(struct Sequence *seq); void build_seqar(struct ListBase *seqbase, struct Sequence ***seqar, int *totseq); + +#define BUILD_SEQAR_COUNT_NOTHING 0 +#define BUILD_SEQAR_COUNT_CURRENT 1 +#define BUILD_SEQAR_COUNT_CHILDREN 2 + +void build_seqar_cb(struct ListBase *seqbase, struct Sequence ***seqar, + int *totseq, int (*test_func)(struct Sequence * seq)); void free_editing(struct Editing *ed); void calc_sequence(struct Sequence *seq); void calc_sequence_disp(struct Sequence *seq); diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index 8b3b2dd6082..b97dbac32ec 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -2269,8 +2269,8 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new) seqn = dupli_seq(seq); if (seqn) { /*should never fail */ seq->flag &= SEQ_DESEL; - seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); - + seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK); + BLI_addtail(new, seqn); if(seq->type==SEQ_META) recurs_dupli_seq(&seq->seqbase,&seqn->seqbase); @@ -2619,7 +2619,7 @@ void make_meta(void) } seq= seq->next; } - if(tot < 2) return; + if(tot < 1) return; if(okee("Make Meta Strip")==0) return; @@ -2763,7 +2763,7 @@ void exit_meta(void) set_last_seq(ms->parseq); - ms->parseq->flag= SELECT; + ms->parseq->flag |= SELECT; recurs_sel_seq(ms->parseq); MEM_freeN(ms); @@ -2859,6 +2859,21 @@ static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag) } } +static int can_transform_seq_test_func(Sequence * seq) +{ + if((seq->flag & SELECT) && !(seq->flag & SEQ_LOCK)) { + return BUILD_SEQAR_COUNT_CURRENT | BUILD_SEQAR_COUNT_CHILDREN; + } + if ((seq->flag & SEQ_LOCK) && !(seq->type & SEQ_EFFECT)) { + if (seq->type != SEQ_META) { + return BUILD_SEQAR_COUNT_NOTHING; + } else { + return BUILD_SEQAR_COUNT_CURRENT; + } + } + return BUILD_SEQAR_COUNT_CURRENT | BUILD_SEQAR_COUNT_CHILDREN; +} + void transform_seq(int mode, int context) { SpaceSeq *sseq= curarea->spacedata.first; @@ -2903,7 +2918,8 @@ void transform_seq(int mode, int context) if(ed==0) return; /* Build the sequence array once, be sure to free it */ - build_seqar( ed->seqbasep, &seqar, &totseq_index ); + build_seqar_cb( ed->seqbasep, &seqar, &totseq_index, + can_transform_seq_test_func ); if (seqar) { for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { @@ -2922,7 +2938,7 @@ void transform_seq(int mode, int context) if(seqar) MEM_freeN(seqar); return; } - + G.moving= 1; last_seq = get_last_seq(); @@ -3116,7 +3132,7 @@ void transform_seq(int mode, int context) if (mode=='g' && !snapskip) { /* Grab */ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) { + if(seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { int myofs; // SEQ_DEBUG_INFO(seq); @@ -3168,7 +3184,7 @@ void transform_seq(int mode, int context) /* Extend, Similar to grab but operate on one side of the cursor */ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) { + if(seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { /* only move the contents of the metastrip otherwise the transformation is applied twice */ if (sequence_is_free_transformable(seq) && seq->type != SEQ_META) { @@ -3280,7 +3296,7 @@ void transform_seq(int mode, int context) /* test for effect and overlap */ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) { + if(seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { seq->flag &= ~SEQ_OVERLAP; if( test_overlap_seq(seq) ) { seq->flag |= SEQ_OVERLAP; @@ -3329,7 +3345,7 @@ void transform_seq(int mode, int context) ts= transmain; for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { - if(seq->flag & SELECT) { + if(seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { seq->start= ts->start; seq->machine= ts->machine; seq->startstill= ts->startstill; diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 9a94f16712c..5faffb38107 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -211,6 +211,66 @@ void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq) *seqar= tseqar; } +static void do_seq_count_cb(ListBase *seqbase, int *totseq, + int (*test_func)(Sequence * seq)) +{ + Sequence *seq; + + seq= seqbase->first; + while(seq) { + int test = test_func(seq); + if (test & BUILD_SEQAR_COUNT_CURRENT) { + (*totseq)++; + } + if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) { + do_seq_count_cb(&seq->seqbase, totseq, test_func); + } + seq= seq->next; + } +} + +static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth, + int (*test_func)(Sequence * seq)) +{ + Sequence *seq; + + seq= seqbase->first; + while(seq) { + int test = test_func(seq); + seq->depth= depth; + + if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) { + do_build_seqar_cb(&seq->seqbase, seqar, depth+1, + test_func); + } + if (test & BUILD_SEQAR_COUNT_CURRENT) { + **seqar= seq; + (*seqar)++; + } + seq= seq->next; + } +} + +void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq, + int (*test_func)(Sequence * seq)) +{ + Sequence **tseqar; + + *totseq= 0; + do_seq_count_cb(seqbase, totseq, test_func); + + if(*totseq==0) { + *seqar= 0; + return; + } + *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar"); + tseqar= *seqar; + + do_build_seqar_cb(seqbase, seqar, 0, test_func); + *seqar= tseqar; +} + + void free_editing(Editing *ed) { MetaStack *ms; From b0b3a69c19fd60e6c48a877b22cab0ba48882c20 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 26 Dec 2007 03:06:59 +0000 Subject: [PATCH 47/99] == Transform: Warp == Adding special hotkey (MMB) to reverse the direction of the warp. Normal input is 0..360 mapped to the horizontal position of the mouse on the 3D view (the 3D view becomes a sort of giant horizontal slider), pressing MMB reverses the value to 0..-360 and back if you press it again. I've used MMB mostly because it's unused in Warp, easily accessible and already used to switches mode for Shear (shear x/y). Indirectly suggested by a user question on ba. --- source/blender/include/transform.h | 1 + source/blender/src/transform.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index b2a3913465f..58cbd5c8755 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -303,6 +303,7 @@ void convertVecToDisplayNum(float *vec, float *num); void convertDisplayNumToVec(float *num, float *vec); void initWarp(TransInfo *t); +int handleEventWarp(TransInfo *t, unsigned short event, short val); int Warp(TransInfo *t, short mval[2]); void initShear(TransInfo *t); diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 632af9e269b..82e7a446de5 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -1399,6 +1399,7 @@ void initWarp(TransInfo *t) t->mode = TFM_WARP; t->transform = Warp; + t->handleEvent = handleEventWarp; t->idx_max = 0; t->num.idx_max = 0; @@ -1435,6 +1436,24 @@ void initWarp(TransInfo *t) t->val= (max[0]-min[0])/2.0f; /* t->val is X dimension projected boundbox */ } +int handleEventWarp(TransInfo *t, unsigned short event, short val) +{ + int status = 0; + + if (event == MIDDLEMOUSE && val) + { + // Use customData pointer to signal warp direction + if (t->customData == 0) + t->customData = (void*)1; + else + t->customData = 0; + + status = 1; + } + + return status; +} + int Warp(TransInfo *t, short mval[2]) { TransData *td = t->data; @@ -1465,6 +1484,11 @@ int Warp(TransInfo *t, short mval[2]) /* amount of degrees for warp */ circumfac= 360.0f * InputHorizontalRatio(t, mval); + + if (t->customData) /* non-null value indicates reversed input */ + { + circumfac *= -1; + } snapGrid(t, &circumfac); applyNumInput(&t->num, &circumfac); From 88e71a5b799e852d6803a8c9075c4b46305e2478 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 26 Dec 2007 09:39:15 +0000 Subject: [PATCH 48/99] == Multires == Cleaned up bad level calls for multires; moved most of multires functions to blenkern, where they should have been in the first place. Functionality of the tool is unchanged. --- .../blender/blenkernel/BKE_bad_level_calls.h | 9 - source/blender/blenkernel/BKE_multires.h | 67 + .../blenkernel/bad_level_call_stubs/stubs.c | 8 +- .../blender/blenkernel/intern/DerivedMesh.c | 3 +- source/blender/blenkernel/intern/mesh.c | 3 +- .../intern}/multires-firstlevel.c | 3 +- source/blender/blenkernel/intern/multires.c | 1393 +++++++++++++++++ source/blender/blenloader/intern/readfile.c | 2 - source/blender/include/multires.h | 28 +- source/blender/python/api2_2x/Mesh.c | 3 +- source/blender/src/buttons_editing.c | 5 +- source/blender/src/editface.c | 2 +- source/blender/src/editmesh.c | 1 + source/blender/src/editobject.c | 2 +- source/blender/src/multires.c | 1387 +--------------- source/blender/src/space.c | 1 + source/blender/src/vpaint.c | 1 + 17 files changed, 1513 insertions(+), 1405 deletions(-) create mode 100644 source/blender/blenkernel/BKE_multires.h rename source/blender/{src => blenkernel/intern}/multires-firstlevel.c (99%) create mode 100644 source/blender/blenkernel/intern/multires.c diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 02e2f799103..923504dfeab 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -207,15 +207,6 @@ void post_layer_create(struct VLayer *vlayer); void post_layer_destroy(struct VLayer *vlayer); void post_server_add(void); -/* multires.c */ -struct Multires; -struct MultiresLevel; -struct MultiresLevel *multires_level_n(struct Multires *mr, int n); -void multires_free(struct Multires *mr); -void multires_set_level(struct Object *ob, struct Mesh *me, const int render); -void multires_update_levels(struct Mesh *me, const int render); -void multires_calc_level_maps(struct MultiresLevel *lvl); -struct Multires *multires_copy(struct Multires *orig); /* sculptmode.c */ struct SculptData; void sculpt_reset_curve(struct SculptData *sd); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h new file mode 100644 index 00000000000..54bf801fd25 --- /dev/null +++ b/source/blender/blenkernel/BKE_multires.h @@ -0,0 +1,67 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 by Nicholas Bishop + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +struct CustomData; +struct EditMesh; +struct Multires; +struct MultiresLevel; +struct Mesh; +struct Object; + +/* Level access */ +struct MultiresLevel *current_level(struct Multires *mr); +struct MultiresLevel *multires_level_n(struct Multires *mr, int n); + +/* Level control */ +void multires_add_level(struct Object *ob, struct Mesh *me, const char subdiv_type); +void multires_set_level(struct Object *ob, struct Mesh *me, const int render); +void multires_free_level(struct MultiresLevel *lvl); + +void multires_edge_level_update(struct Object *ob, struct Mesh *me); + +void multires_free(struct Multires *mr); +struct Multires *multires_copy(struct Multires *orig); +void multires_create(struct Mesh *me); + +/* CustomData */ +void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n); +void multires_add_layer(struct Mesh *me, struct CustomData *cd, const int type, const int n); +void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl); +/* After adding or removing vcolor layers, run this */ +void multires_load_cols(struct Mesh *me); + +/* Private (used in multires-firstlevel.c) */ +void multires_level_to_mesh(struct Object *ob, struct Mesh *me, const int render); +void multires_update_levels(struct Mesh *me, const int render); +void multires_update_first_level(struct Mesh *me, struct EditMesh *em); +void multires_update_customdata(struct MultiresLevel *lvl1, struct CustomData *src, + struct CustomData *dst, const int type); +void multires_customdata_to_mesh(struct Mesh *me, struct EditMesh *em, + struct MultiresLevel *lvl, struct CustomData *src, + struct CustomData *dst, const int type); diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index e0aa288c7b2..8885d4db760 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -310,13 +310,7 @@ void post_geometry_free_constraint(struct VNode *vnode) {} void post_layer_create(struct VLayer *vlayer) {} void post_layer_destroy(struct VLayer *vlayer) {} void post_server_add(void) {} - /* Multires/sculpt stubs */ -struct MultiresLevel *multires_level_n(struct Multires *mr, int n) {return NULL;} -void multires_free(struct Multires *mr) {} -void multires_set_level(struct Object *ob, struct Mesh *me, const int render) {} -void multires_update_levels(struct Mesh *me, const int render) {} -void multires_calc_level_maps(struct MultiresLevel *lvl) {} -struct Multires *multires_copy(struct Multires *orig) {return NULL;} + /* sculpt stubs */ void sculpt_reset_curve(struct SculptData *sd) {} void sculptmode_init(struct Scene *sce) {} void sculptmode_free_all(struct Scene *sce) {} diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 9d51fc645ba..aada60be21b 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -74,6 +74,7 @@ #include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_object.h" #include "BKE_subsurf.h" #include "BKE_texture.h" @@ -87,8 +88,6 @@ #include "BIF_gl.h" #include "BIF_glutil.h" -#include "multires.h" - // headers for fluidsim bobj meshes #include #include "LBM_fluidsim.h" diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 56b1fe7e75b..6156b2bed89 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -63,6 +63,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_subsurf.h" #include "BKE_displist.h" #include "BKE_library.h" @@ -83,8 +84,6 @@ #include "BLI_editVert.h" #include "BLI_arithb.h" -#include "multires.h" - int update_realtime_texture(MTFace *tface, double time) { Image *ima; diff --git a/source/blender/src/multires-firstlevel.c b/source/blender/blenkernel/intern/multires-firstlevel.c similarity index 99% rename from source/blender/src/multires-firstlevel.c rename to source/blender/blenkernel/intern/multires-firstlevel.c index 2be867b5db0..778dd6f9c77 100644 --- a/source/blender/src/multires-firstlevel.c +++ b/source/blender/blenkernel/intern/multires-firstlevel.c @@ -43,13 +43,13 @@ #include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BLI_editVert.h" #include "MEM_guardedalloc.h" #include "blendef.h" -#include "multires.h" #include @@ -392,7 +392,6 @@ void multires_delete_layer(Mesh *me, CustomData *cd, const int type, int n) } } -MultiresLevel *current_level(Multires *mr); void multires_add_layer(Mesh *me, CustomData *cd, const int type, const int n) { if(me && me->mr && cd) { diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c new file mode 100644 index 00000000000..2b50f37e7a1 --- /dev/null +++ b/source/blender/blenkernel/intern/multires.c @@ -0,0 +1,1393 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 by Nicholas Bishop + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_vec_types.h" + +#include "BDR_sculptmode.h" + +#include "BIF_editmesh.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + +#include "BKE_customdata.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_multires.h" + +#include "blendef.h" +#include "editmesh.h" + +#include + +/* Returns the active multires level (currently applied to the mesh) */ +MultiresLevel *current_level(Multires *mr) +{ + return BLI_findlink(&mr->levels, mr->current - 1); +} + +/* Returns the nth multires level, starting at 1 */ +MultiresLevel *multires_level_n(Multires *mr, int n) +{ + if(mr) + return BLI_findlink(&mr->levels, n - 1); + else + return NULL; +} + +/* Free and clear the temporary connectivity data */ +static void multires_free_temp_data(MultiresLevel *lvl) +{ + if(lvl) { + if(lvl->edge_boundary_states) MEM_freeN(lvl->edge_boundary_states); + if(lvl->vert_edge_map) MEM_freeN(lvl->vert_edge_map); + if(lvl->vert_face_map) MEM_freeN(lvl->vert_face_map); + if(lvl->map_mem) MEM_freeN(lvl->map_mem); + + lvl->edge_boundary_states = NULL; + lvl->vert_edge_map = lvl->vert_face_map = NULL; + lvl->map_mem = NULL; + } +} + +/* Does not actually free lvl itself */ +void multires_free_level(MultiresLevel *lvl) +{ + if(lvl) { + if(lvl->faces) MEM_freeN(lvl->faces); + if(lvl->edges) MEM_freeN(lvl->edges); + if(lvl->colfaces) MEM_freeN(lvl->colfaces); + + multires_free_temp_data(lvl); + } +} + +void multires_free(Multires *mr) +{ + if(mr) { + MultiresLevel* lvl= mr->levels.first; + + /* Free the first-level data */ + if(lvl) { + CustomData_free(&mr->vdata, lvl->totvert); + CustomData_free(&mr->fdata, lvl->totface); + MEM_freeN(mr->edge_flags); + MEM_freeN(mr->edge_creases); + } + + while(lvl) { + multires_free_level(lvl); + lvl= lvl->next; + } + + MEM_freeN(mr->verts); + + BLI_freelistN(&mr->levels); + + MEM_freeN(mr); + } +} + +static MultiresLevel *multires_level_copy(MultiresLevel *orig) +{ + if(orig) { + MultiresLevel *lvl= MEM_dupallocN(orig); + + lvl->next= lvl->prev= NULL; + lvl->faces= MEM_dupallocN(orig->faces); + lvl->colfaces= MEM_dupallocN(orig->colfaces); + lvl->edges= MEM_dupallocN(orig->edges); + lvl->edge_boundary_states = NULL; + lvl->vert_edge_map= lvl->vert_face_map= NULL; + lvl->map_mem= NULL; + + return lvl; + } + return NULL; +} + +Multires *multires_copy(Multires *orig) +{ + const CustomDataMask vdata_mask= CD_MASK_MDEFORMVERT; + + if(orig) { + Multires *mr= MEM_dupallocN(orig); + MultiresLevel *lvl; + + mr->levels.first= mr->levels.last= NULL; + + for(lvl= orig->levels.first; lvl; lvl= lvl->next) + BLI_addtail(&mr->levels, multires_level_copy(lvl)); + + mr->verts= MEM_dupallocN(orig->verts); + + lvl= mr->levels.first; + if(lvl) { + CustomData_copy(&orig->vdata, &mr->vdata, vdata_mask, CD_DUPLICATE, lvl->totvert); + CustomData_copy(&orig->fdata, &mr->fdata, CD_MASK_MTFACE, CD_DUPLICATE, lvl->totface); + mr->edge_flags= MEM_dupallocN(orig->edge_flags); + mr->edge_creases= MEM_dupallocN(orig->edge_creases); + } + + return mr; + } + return NULL; +} + +static void multires_get_vert(MVert *out, EditVert *eve, MVert *m, int i) +{ + if(eve) { + VecCopyf(out->co, eve->co); + out->flag= 0; + if(eve->f & SELECT) out->flag |= 1; + if(eve->h) out->flag |= ME_HIDE; + eve->tmp.l= i; + } + else + *out= *m; +} + +void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease) +{ + if(!eed || !flag) return; + + /* Would be nice if EditMesh edge flags could be unified with Mesh flags! */ + *flag= (eed->f & SELECT) | ME_EDGERENDER; + if(eed->f2<2) *flag |= ME_EDGEDRAW; + if(eed->f2==0) *flag |= ME_LOOSEEDGE; + if(eed->sharp) *flag |= ME_SHARP; + if(eed->seam) *flag |= ME_SEAM; + if(eed->h & EM_FGON) *flag |= ME_FGON; + if(eed->h & 1) *flag |= ME_HIDE; + + *crease= (char)(255.0*eed->crease); +} + +static void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag, char *crease) +{ + if(eed) { + e->v[0]= eed->v1->tmp.l; + e->v[1]= eed->v2->tmp.l; + eed_to_medge_flag(eed, flag, crease); + } else { + e->v[0]= m->v1; + e->v[1]= m->v2; + *flag= m->flag; + *crease= m->crease; + } +} + +static void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m) +{ + if(efa) { + MFace tmp; + int j; + tmp.v1= efa->v1->tmp.l; + tmp.v2= efa->v2->tmp.l; + tmp.v3= efa->v3->tmp.l; + tmp.v4= 0; + if(efa->v4) tmp.v4= efa->v4->tmp.l; + test_index_face(&tmp, NULL, 0, efa->v4?4:3); + for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j]; + + /* Flags */ + f->flag= efa->flag; + if(efa->f & 1) f->flag |= ME_FACE_SEL; + else f->flag &= ~ME_FACE_SEL; + if(efa->h) f->flag |= ME_HIDE; + f->mat_nr= efa->mat_nr; + } else { + f->v[0]= m->v1; + f->v[1]= m->v2; + f->v[2]= m->v3; + f->v[3]= m->v4; + f->flag= m->flag; + f->mat_nr= m->mat_nr; + } +} + +/* For manipulating vertex colors / uvs */ +static void mcol_to_multires(MultiresColFace *mrf, MCol *mcol) +{ + char i; + for(i=0; i<4; ++i) { + mrf->col[i].a= mcol[i].a; + mrf->col[i].r= mcol[i].r; + mrf->col[i].g= mcol[i].g; + mrf->col[i].b= mcol[i].b; + } +} + +/* 1 <= count <= 4 */ +static void multires_col_avg(MultiresCol *avg, MultiresCol cols[4], char count) +{ + unsigned i; + avg->a= avg->r= avg->g= avg->b= 0; + for(i=0; ia+= cols[i].a; + avg->r+= cols[i].r; + avg->g+= cols[i].g; + avg->b+= cols[i].b; + } + avg->a/= count; + avg->r/= count; + avg->g/= count; + avg->b/= count; +} + +static void multires_col_avg2(MultiresCol *avg, MultiresCol *c1, MultiresCol *c2) +{ + MultiresCol in[2]; + in[0]= *c1; + in[1]= *c2; + multires_col_avg(avg,in,2); +} + +void multires_load_cols(Mesh *me) +{ + MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *cur; + EditMesh *em= G.obedit ? G.editMesh : NULL; + CustomData *src= em ? &em->fdata : &me->fdata; + EditFace *efa= NULL; + unsigned i,j; + + if(!CustomData_has_layer(src, CD_MCOL) && !CustomData_has_layer(src, CD_MTFACE)) return; + + /* Add texcol data */ + for(cur= me->mr->levels.first; cur; cur= cur->next) + if(!cur->colfaces) + cur->colfaces= MEM_callocN(sizeof(MultiresColFace)*cur->totface,"ColFaces"); + + me->mr->use_col= CustomData_has_layer(src, CD_MCOL); + + if(em) efa= em->faces.first; + for(i=0; itotface; ++i) { + MultiresColFace *f= &lvl->colfaces[i]; + + if(me->mr->use_col) + mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]); + + if(em) efa= efa->next; + } + + /* Update higher levels */ + lvl= lvl->next; + while(lvl) { + MultiresColFace *cf= lvl->colfaces; + for(i=0; iprev->totface; ++i) { + const char sides= lvl->prev->faces[i].v[3]?4:3; + MultiresCol cntr; + + /* Find average color of 4 (or 3 for triangle) verts */ + multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides); + + for(j=0; jprev->colfaces[i]; + + multires_col_avg2(&cf->col[0], + &pf->col[j], + &pf->col[j==0?sides-1:j-1]); + cf->col[1]= pf->col[j]; + multires_col_avg2(&cf->col[2], + &pf->col[j], + &pf->col[j==sides-1?0:j+1]); + cf->col[3]= cntr; + + ++cf; + } + } + lvl= lvl->next; + } + + /* Update lower levels */ + lvl= me->mr->levels.last; + lvl= lvl->prev; + while(lvl) { + unsigned curf= 0; + for(i=0; itotface; ++i) { + MultiresFace *f= &lvl->faces[i]; + for(j=0; j<(f->v[3]?4:3); ++j) { + lvl->colfaces[i].col[j]= lvl->next->colfaces[curf].col[1]; + ++curf; + } + } + lvl= lvl->prev; + } +} + +void multires_create(Mesh *me) +{ + MultiresLevel *lvl; + EditMesh *em= G.obedit ? G.editMesh : NULL; + EditVert *eve= NULL; + EditFace *efa= NULL; + EditEdge *eed= NULL; + int i; + + lvl= MEM_callocN(sizeof(MultiresLevel), "multires level"); + + if(me->pv) sculptmode_pmv_off(me); + + me->mr= MEM_callocN(sizeof(Multires), "multires data"); + + BLI_addtail(&me->mr->levels,lvl); + me->mr->current= 1; + me->mr->level_count= 1; + me->mr->edgelvl= 1; + me->mr->pinlvl= 1; + me->mr->renderlvl= 1; + + /* Load mesh (or editmesh) into multires data */ + + /* Load vertices and vdata (MDeformVerts) */ + lvl->totvert= em ? BLI_countlist(&em->verts) : me->totvert; + me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts"); + multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata, + &me->mr->vdata, CD_MDEFORMVERT); + if(em) eve= em->verts.first; + for(i=0; itotvert; ++i) { + multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i); + if(em) eve= eve->next; + } + + /* Load faces and fdata (MTFaces) */ + lvl->totface= em ? BLI_countlist(&em->faces) : me->totface; + lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces"); + multires_update_customdata(me->mr->levels.first, em ? &em->fdata : &me->fdata, + &me->mr->fdata, CD_MTFACE); + if(em) efa= em->faces.first; + for(i=0; itotface; ++i) { + multires_get_face(&lvl->faces[i], efa, &me->mface[i]); + if(em) efa= efa->next; + } + + /* Load edges and edge_flags */ + lvl->totedge= em ? BLI_countlist(&em->edges) : me->totedge; + lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges"); + me->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge flags"); + me->mr->edge_creases= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge creases"); + if(em) eed= em->edges.first; + for(i=0; itotedge; ++i) { + multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i], &me->mr->edge_creases[i]); + if(em) eed= eed->next; + } + + multires_load_cols(me); +} + +typedef struct MultiresMapNode { + struct MultiresMapNode *next, *prev; + unsigned Index; +} MultiresMapNode; + +/* Produces temporary connectivity data for the multires lvl */ +static void multires_calc_temp_data(MultiresLevel *lvl) +{ + unsigned i, j, emax; + MultiresMapNode *indexnode= NULL; + + lvl->map_mem= MEM_mallocN(sizeof(MultiresMapNode)*(lvl->totedge*2 + lvl->totface*4), "map_mem"); + indexnode= lvl->map_mem; + + /* edge map */ + lvl->vert_edge_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_edge_map"); + for(i=0; itotedge; ++i) { + for(j=0; j<2; ++j, ++indexnode) { + indexnode->Index= i; + BLI_addtail(&lvl->vert_edge_map[lvl->edges[i].v[j]], indexnode); + } + } + + /* face map */ + lvl->vert_face_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_face_map"); + for(i=0; itotface; ++i){ + for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j, ++indexnode) { + indexnode->Index= i; + BLI_addtail(&lvl->vert_face_map[lvl->faces[i].v[j]], indexnode); + } + } + + /* edge boundaries */ + emax = (lvl->prev ? (lvl->prev->totedge * 2) : lvl->totedge); + lvl->edge_boundary_states= MEM_callocN(sizeof(char)*lvl->totedge, "edge_boundary_states"); + for(i=0; ivert_face_map[lvl->edges[i].v[0]].first; + unsigned total= 0; + + lvl->edge_boundary_states[i] = 1; + while(n1 && lvl->edge_boundary_states[i] == 1) { + MultiresMapNode *n2= lvl->vert_face_map[lvl->edges[i].v[1]].first; + while(n2) { + if(n1->Index == n2->Index) { + ++total; + + if(total > 1) { + lvl->edge_boundary_states[i] = 0; + break; + } + } + + n2= n2->next; + } + n1= n1->next; + } + } +} + +/* CATMULL-CLARK + ============= */ + +typedef struct MultiApplyData { + /* Smooth faces */ + float *corner1, *corner2, *corner3, *corner4; + char quad; + + /* Smooth edges */ + char boundary; + float edge_face_neighbor_midpoints_accum[3]; + unsigned edge_face_neighbor_midpoints_total; + float *endpoint1, *endpoint2; + + /* Smooth verts */ + /* uses 'char boundary' */ + float *original; + int edge_count; + float vert_face_neighbor_midpoints_average[3]; + float vert_edge_neighbor_midpoints_average[3]; + float boundary_edges_average[3]; +} MultiApplyData; + +/* Simply averages the four corners of a polygon. */ +static float catmullclark_smooth_face(MultiApplyData *data, const unsigned i) +{ + const float total= data->corner1[i]+data->corner2[i]+data->corner3[i]; + return data->quad ? (total+data->corner4[i])/4 : total/3; +} + +static float catmullclark_smooth_edge(MultiApplyData *data, const unsigned i) +{ + float accum= 0; + unsigned count= 2; + + accum+= data->endpoint1[i] + data->endpoint2[i]; + + if(!data->boundary) { + accum+= data->edge_face_neighbor_midpoints_accum[i]; + count+= data->edge_face_neighbor_midpoints_total; + } + + return accum / count; +} + +static float catmullclark_smooth_vert(MultiApplyData *data, const unsigned i) +{ + if(data->boundary) { + return data->original[i]*0.75 + data->boundary_edges_average[i]*0.25; + } else { + return (data->vert_face_neighbor_midpoints_average[i] + + 2*data->vert_edge_neighbor_midpoints_average[i] + + data->original[i]*(data->edge_count-3))/data->edge_count; + } +} + + + +/* Call func count times, passing in[i] as the input and storing the output in out[i] */ +static void multi_apply(float *out, MultiApplyData *data, + const unsigned count, float (*func)(MultiApplyData *, const unsigned)) +{ + unsigned i; + for(i=0; ivert_edge_map[v].first; + while(node) { + if(lvl->edge_boundary_states[node->Index]) + return 1; + node= node->next; + } + return 0; +} + +#define GET_FLOAT(array, i, j, stride) (((float*)((char*)(array)+((i)*(stride))))[(j)]) + +static void edge_face_neighbor_midpoints_accum(MultiApplyData *data, MultiresLevel *lvl, + void *array, const char stride, const MultiresEdge *e) +{ + ListBase *neighbors1= &lvl->vert_face_map[e->v[0]]; + ListBase *neighbors2= &lvl->vert_face_map[e->v[1]]; + MultiresMapNode *n1, *n2; + unsigned j,count= 0; + float *out= data->edge_face_neighbor_midpoints_accum; + + out[0]=out[1]=out[2]= 0; + + for(n1= neighbors1->first; n1; n1= n1->next) { + for(n2= neighbors2->first; n2; n2= n2->next) { + if(n1->Index == n2->Index) { + for(j=0; j<3; ++j) + out[j]+= GET_FLOAT(array,lvl->faces[n1->Index].mid,j,stride); + ++count; + } + } + } + + data->edge_face_neighbor_midpoints_total= count; +} + +static void vert_face_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl, + void *array, const char stride, const unsigned i) +{ + ListBase *neighbors= &lvl->vert_face_map[i]; + MultiresMapNode *n1; + unsigned j,count= 0; + float *out= data->vert_face_neighbor_midpoints_average; + + out[0]=out[1]=out[2]= 0; + + for(n1= neighbors->first; n1; n1= n1->next) { + for(j=0; j<3; ++j) + out[j]+= GET_FLOAT(array,lvl->faces[n1->Index].mid,j,stride); + ++count; + } + for(j=0; j<3; ++j) out[j]/= count; +} + +static void vert_edge_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl, + void *array, const char stride, const unsigned i) +{ + ListBase *neighbors= &lvl->vert_edge_map[i]; + MultiresMapNode *n1; + unsigned j,count= 0; + float *out= data->vert_edge_neighbor_midpoints_average; + + out[0]=out[1]=out[2]= 0; + + for(n1= neighbors->first; n1; n1= n1->next) { + for(j=0; j<3; ++j) + out[j]+= (GET_FLOAT(array,lvl->edges[n1->Index].v[0],j,stride) + + GET_FLOAT(array,lvl->edges[n1->Index].v[1],j,stride)) / 2; + ++count; + } + for(j=0; j<3; ++j) out[j]/= count; +} + +static void boundary_edges_average(MultiApplyData *data, MultiresLevel *lvl, + void *array, const char stride, const unsigned i) +{ + ListBase *neighbors= &lvl->vert_edge_map[i]; + MultiresMapNode *n1; + unsigned j,count= 0; + float *out= data->boundary_edges_average; + + out[0]=out[1]=out[2]= 0; + + for(n1= neighbors->first; n1; n1= n1->next) { + const MultiresEdge *e= &lvl->edges[n1->Index]; + const unsigned end= e->v[0]==i ? e->v[1] : e->v[0]; + + if(lvl->edge_boundary_states[n1->Index]) { + for(j=0; j<3; ++j) + out[j]+= GET_FLOAT(array,end,j,stride); + ++count; + } + } + for(j=0; j<3; ++j) out[j]/= count; +} + +/* END CATMULL-CLARK + ================= */ + +/* Update vertex locations and vertex flags */ +static void multires_update_vertices(Mesh *me, EditMesh *em) +{ + MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL, + *last_lvl= me->mr->levels.last; + vec3f *pr_deltas= NULL, *cr_deltas= NULL, *swap_deltas= NULL; + EditVert *eve= NULL; + MultiApplyData data; + int i, j; + + /* Prepare deltas */ + pr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 1"); + cr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 2"); + + /* Calculate initial deltas -- current mesh subtracted from current level*/ + if(em) eve= em->verts.first; + for(i=0; itotvert; ++i) { + if(em) { + VecSubf(&cr_deltas[i].x, eve->co, me->mr->verts[i].co); + eve= eve->next; + } else + VecSubf(&cr_deltas[i].x, me->mvert[i].co, me->mr->verts[i].co); + } + + + /* Copy current level's vertex flags and clear the rest */ + if(em) eve= em->verts.first; + for(i=0; i < last_lvl->totvert; ++i) { + if(i < cr_lvl->totvert) { + MVert mvflag; + multires_get_vert(&mvflag, eve, &me->mvert[i], i); + if(em) eve= eve->next; + me->mr->verts[i].flag= mvflag.flag; + } + else + me->mr->verts[i].flag= 0; + } + + /* If already on the highest level, copy current verts (including flags) into current level */ + if(cr_lvl == last_lvl) { + if(em) + eve= em->verts.first; + for(i=0; itotvert; ++i) { + multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i); + if(em) eve= eve->next; + } + } + + /* Update higher levels */ + pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); + cr_lvl= pr_lvl->next; + while(cr_lvl) { + multires_calc_temp_data(pr_lvl); + + /* Swap the old/new deltas */ + swap_deltas= pr_deltas; + pr_deltas= cr_deltas; + cr_deltas= swap_deltas; + + /* Calculate and add new deltas + ============================ */ + for(i=0; itotface; ++i) { + const MultiresFace *f= &pr_lvl->faces[i]; + data.corner1= &pr_deltas[f->v[0]].x; + data.corner2= &pr_deltas[f->v[1]].x; + data.corner3= &pr_deltas[f->v[2]].x; + data.corner4= &pr_deltas[f->v[3]].x; + data.quad= f->v[3] ? 1 : 0; + multi_apply(&cr_deltas[f->mid].x, &data, 3, catmullclark_smooth_face); + + for(j=0; j<(data.quad?4:3); ++j) + me->mr->verts[f->mid].flag |= me->mr->verts[f->v[j]].flag; + } + + for(i=0; itotedge; ++i) { + const MultiresEdge *e= &pr_lvl->edges[i]; + data.boundary= pr_lvl->edge_boundary_states[i]; + edge_face_neighbor_midpoints_accum(&data,pr_lvl,cr_deltas,sizeof(vec3f),e); + data.endpoint1= &pr_deltas[e->v[0]].x; + data.endpoint2= &pr_deltas[e->v[1]].x; + multi_apply(&cr_deltas[e->mid].x, &data, 3, catmullclark_smooth_edge); + + for(j=0; j<2; ++j) + me->mr->verts[e->mid].flag |= me->mr->verts[e->v[j]].flag; + } + + for(i=0; itotvert; ++i) { + data.boundary= multires_vert_is_boundary(pr_lvl,i); + data.original= &pr_deltas[i].x; + data.edge_count= BLI_countlist(&pr_lvl->vert_edge_map[i]); + if(data.boundary) + boundary_edges_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i); + else { + vert_face_neighbor_midpoints_average(&data,pr_lvl,cr_deltas,sizeof(vec3f),i); + vert_edge_neighbor_midpoints_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i); + } + multi_apply(&cr_deltas[i].x, &data, 3, catmullclark_smooth_vert); + } + + /* Apply deltas to vertex locations */ + for(i=0; (cr_lvl == last_lvl) && (i < cr_lvl->totvert); ++i) { + VecAddf(me->mr->verts[i].co, + me->mr->verts[i].co, + &cr_deltas[i].x); + } + + multires_free_temp_data(pr_lvl); + + pr_lvl= pr_lvl->next; + cr_lvl= cr_lvl->next; + } + if(pr_deltas) MEM_freeN(pr_deltas); + if(cr_deltas) MEM_freeN(cr_deltas); + +} + +static void multires_update_faces(Mesh *me, EditMesh *em) +{ + MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL, + *last_lvl= me->mr->levels.last; + char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *or_flag_damaged= NULL, + *pr_mat_damaged= NULL, *cr_mat_damaged= NULL, *or_mat_damaged= NULL, *swap= NULL; + EditFace *efa= NULL; + unsigned i,j,curf; + + /* Find for each face whether flag/mat has changed */ + pr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1"); + cr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1"); + pr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1"); + cr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1"); + if(em) efa= em->faces.first; + for(i=0; itotface; ++i) { + MultiresFace mftmp; + multires_get_face(&mftmp, efa, &me->mface[i]); + if(cr_lvl->faces[i].flag != mftmp.flag) + cr_flag_damaged[i]= 1; + if(cr_lvl->faces[i].mat_nr != mftmp.mat_nr) + cr_mat_damaged[i]= 1; + + /* Update current level */ + cr_lvl->faces[i].flag= mftmp.flag; + cr_lvl->faces[i].mat_nr= mftmp.mat_nr; + + if(em) efa= efa->next; + } + or_flag_damaged= MEM_dupallocN(cr_flag_damaged); + or_mat_damaged= MEM_dupallocN(cr_mat_damaged); + + /* Update lower levels */ + cr_lvl= cr_lvl->prev; + while(cr_lvl) { + swap= pr_flag_damaged; + pr_flag_damaged= cr_flag_damaged; + cr_flag_damaged= swap; + + swap= pr_mat_damaged; + pr_mat_damaged= cr_mat_damaged; + cr_mat_damaged= swap; + + curf= 0; + for(i=0; itotface; ++i) { + const int sides= cr_lvl->faces[i].v[3] ? 4 : 3; + + /* Check damages */ + for(j=0; jfaces[i].flag= cr_lvl->next->faces[curf].flag; + cr_flag_damaged[i]= 1; + } + if(pr_mat_damaged[curf]) { + cr_lvl->faces[i].mat_nr= cr_lvl->next->faces[curf].mat_nr; + cr_mat_damaged[i]= 1; + } + } + } + + cr_lvl= cr_lvl->prev; + } + + /* Clear to original damages */ + if(cr_flag_damaged) MEM_freeN(cr_flag_damaged); + if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); + cr_flag_damaged= or_flag_damaged; + cr_mat_damaged= or_mat_damaged; + + /* Update higher levels */ + pr_lvl= current_level(me->mr); + cr_lvl= pr_lvl->next; + while(cr_lvl) { + swap= pr_flag_damaged; + pr_flag_damaged= cr_flag_damaged; + cr_flag_damaged= swap; + + swap= pr_mat_damaged; + pr_mat_damaged= cr_mat_damaged; + cr_mat_damaged= swap; + + /* Update faces */ + for(i=0, curf= 0; itotface; ++i) { + const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3; + for(j=0; jfaces[curf].flag= pr_lvl->faces[i].flag; + cr_flag_damaged[curf]= 1; + } + if(pr_mat_damaged[i]) { + cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr; + cr_mat_damaged[curf]= 1; + } + } + } + + pr_lvl= pr_lvl->next; + cr_lvl= cr_lvl->next; + } + + if(pr_flag_damaged) MEM_freeN(pr_flag_damaged); + if(cr_flag_damaged) MEM_freeN(cr_flag_damaged); + if(pr_mat_damaged) MEM_freeN(pr_mat_damaged); + if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); +} + +void multires_update_colors(Mesh *me) +{ + MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); + MultiresCol *pr_deltas= NULL, *cr_deltas= NULL; + EditMesh *em= G.obedit ? G.editMesh : NULL; + CustomData *src= em ? &em->fdata : &me->fdata; + EditFace *efa= NULL; + unsigned i,j,curf= 0; + + if(me->mr->use_col) { + /* Calc initial deltas */ + cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"initial color/uv deltas"); + + if(em) efa= em->faces.first; + for(i=0; itotface; ++i) { + MCol *col= em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]; + for(j=0; j<4; ++j) { + if(me->mr->use_col) { + cr_deltas[i*4+j].a= col[j].a - lvl->colfaces[i].col[j].a; + cr_deltas[i*4+j].r= col[j].r - lvl->colfaces[i].col[j].r; + cr_deltas[i*4+j].g= col[j].g - lvl->colfaces[i].col[j].g; + cr_deltas[i*4+j].b= col[j].b - lvl->colfaces[i].col[j].b; + } + } + if(em) efa= efa->next; + } + + /* Update current level */ + if(em) efa= em->faces.first; + for(i=0; itotface; ++i) { + MultiresColFace *f= &lvl->colfaces[i]; + + if(me->mr->use_col) + mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]); + + if(em) efa= efa->next; + } + + /* Update higher levels */ + lvl= lvl->next; + while(lvl) { + /* Set up new deltas, but keep the ones from the previous level */ + if(pr_deltas) MEM_freeN(pr_deltas); + pr_deltas= cr_deltas; + cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"color deltas"); + + curf= 0; + for(i=0; iprev->totface; ++i) { + const char sides= lvl->prev->faces[i].v[3]?4:3; + MultiresCol cntr; + + /* Find average color of 4 (or 3 for triangle) verts */ + multires_col_avg(&cntr,&pr_deltas[i*4],sides); + + for(j=0; jtotface; ++i) { + for(j=0; j<4; ++j) { + lvl->colfaces[i].col[j].a+= cr_deltas[i*4+j].a; + lvl->colfaces[i].col[j].r+= cr_deltas[i*4+j].r; + lvl->colfaces[i].col[j].g+= cr_deltas[i*4+j].g; + lvl->colfaces[i].col[j].b+= cr_deltas[i*4+j].b; + } + } + + lvl= lvl->next; + } + if(pr_deltas) MEM_freeN(pr_deltas); + if(cr_deltas) MEM_freeN(cr_deltas); + + /* Update lower levels */ + lvl= me->mr->levels.last; + lvl= lvl->prev; + while(lvl) { + MultiresColFace *nf= lvl->next->colfaces; + for(i=0; itotface; ++i) { + MultiresFace *f= &lvl->faces[i]; + for(j=0; j<(f->v[3]?4:3); ++j) { + lvl->colfaces[i].col[j]= nf->col[1]; + ++nf; + } + } + lvl= lvl->prev; + } + } +} + +void multires_update_levels(Mesh *me, const int render) +{ + EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; + + multires_update_first_level(me, em); + multires_update_vertices(me, em); + multires_update_faces(me, em); + multires_update_colors(me); +} + +static void check_colors(Mesh *me) +{ + CustomData *src= G.obedit ? &G.editMesh->fdata : &me->fdata; + const char col= CustomData_has_layer(src, CD_MCOL); + + /* Check if vertex colors have been deleted or added */ + if(me->mr->use_col && !col) + me->mr->use_col= 0; + else if(!me->mr->use_col && col) { + me->mr->use_col= 1; + multires_load_cols(me); + } +} + +static unsigned int find_mid_edge(ListBase *vert_edge_map, + MultiresLevel *lvl, + const unsigned int v1, + const unsigned int v2 ) +{ + MultiresMapNode *n= vert_edge_map[v1].first; + while(n) { + if(lvl->edges[n->Index].v[0]==v2 || + lvl->edges[n->Index].v[1]==v2) + return lvl->edges[n->Index].mid; + + n= n->next; + } + return -1; +} + +static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed) +{ + if(!eed) return; + + if(flag & ME_SEAM) eed->seam= 1; + if(flag & ME_SHARP) eed->sharp = 1; + if(flag & SELECT) eed->f |= SELECT; + if(flag & ME_FGON) eed->h= EM_FGON; + if(flag & ME_HIDE) eed->h |= 1; + + eed->crease= ((float)crease)/255.0; +} + +static float clamp_component(const float c) +{ + if(c<0) return 0; + else if(c>255) return 255; + else return c; +} + +static void multires_to_mcol(MultiresColFace *f, MCol mcol[4]) +{ + unsigned char j; + for(j=0; j<4; ++j) { + mcol->a= clamp_component(f->col[j].a); + mcol->r= clamp_component(f->col[j].r); + mcol->g= clamp_component(f->col[j].g); + mcol->b= clamp_component(f->col[j].b); + ++mcol; + } +} + +void multires_level_to_mesh(Object *ob, Mesh *me, const int render) +{ + MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); + int i; + EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; + EditVert **eves= NULL; + EditEdge *eed= NULL; + + if(em) { + /* Remove editmesh elements */ + free_editMesh(em); + + eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers"); + } else { + CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); + CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); + CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface); + CustomData_free_layers(&me->fdata, CD_MCOL, me->totface); + + me->totvert= lvl->totvert; + me->totface= lvl->totface; + me->totedge= lvl->totedge; + + CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); + CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); + CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); + mesh_update_customdata_pointers(me); + } + + /* Vertices/Edges/Faces */ + + for(i=0; itotvert; ++i) { + if(em) { + eves[i]= addvertlist(me->mr->verts[i].co, NULL); + if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT; + if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1; + eves[i]->data= NULL; + } + else + me->mvert[i]= me->mr->verts[i]; + } + for(i=0; itotedge; ++i) { + if(em) { + addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL); + } else { + me->medge[i].v1= lvl->edges[i].v[0]; + me->medge[i].v2= lvl->edges[i].v[1]; + me->medge[i].flag &= ~ME_HIDE; + } + } + for(i=0; itotface; ++i) { + if(em) { + EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL; + EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]], + eves[lvl->faces[i].v[2]], eve4, NULL, NULL); + efa->flag= lvl->faces[i].flag & ~ME_HIDE; + efa->mat_nr= lvl->faces[i].mat_nr; + if(lvl->faces[i].flag & ME_FACE_SEL) + efa->f |= SELECT; + if(lvl->faces[i].flag & ME_HIDE) efa->h= 1; + efa->data= NULL; + } + else { + me->mface[i].v1= lvl->faces[i].v[0]; + me->mface[i].v2= lvl->faces[i].v[1]; + me->mface[i].v3= lvl->faces[i].v[2]; + me->mface[i].v4= lvl->faces[i].v[3]; + me->mface[i].flag= lvl->faces[i].flag; + me->mface[i].flag &= ~ME_HIDE; + me->mface[i].mat_nr= lvl->faces[i].mat_nr; + } + } + + /* Edge flags */ + if(em) eed= em->edges.first; + if(lvl==me->mr->levels.first) { + for(i=0; itotedge; ++i) { + if(em) { + medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed); + eed= eed->next; + } + else { + me->medge[i].flag= me->mr->edge_flags[i]; + me->medge[i].crease= me->mr->edge_creases[i]; + } + } + } else { + MultiresLevel *lvl1= me->mr->levels.first; + const int last= lvl1->totedge * pow(2, me->mr->current-1); + for(i=0; imr->current-1); + + if(em) { + medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed); + eed= eed->next; + } + else { + me->medge[i].flag= me->mr->edge_flags[ndx]; + me->medge[i].crease= me->mr->edge_creases[ndx]; + } + } + } + + if(em) { + eed= em->edges.first; + for(i=0, eed= em->edges.first; itotedge; ++i, eed= eed->next) { + eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE || + me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE; + } + } + + EM_select_flush(); + + multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT); + multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE); + + /* Colors */ + if(me->mr->use_col) { + MCol c[4]; + EditFace *efa= NULL; + CustomData *src= em ? &em->fdata : &me->fdata; + if(em) { + if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL); + efa= em->faces.first; + } + else { + if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface); + } + + for(i=0; itotface; ++i) { + if(em) { + if(me->mr->use_col) { + multires_to_mcol(&lvl->colfaces[i], c); + CustomData_em_set(src, efa->data, CD_MCOL, c); + } + efa= efa->next; + } + else if(me->mr->use_col) multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]); + } + + } + + mesh_update_customdata_pointers(me); + + if(em) { + MEM_freeN(eves); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + recalc_editnormals(); + } else { + multires_edge_level_update(ob,me); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); + } +} + +void multires_add_level(Object *ob, Mesh *me, const char subdiv_type) +{ + int i,j, curf, cure; + MultiresLevel *lvl= NULL; + MultiApplyData data; + MVert *oldverts= NULL; + + lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel"); + if(me->pv) sculptmode_pmv_off(me); + + check_colors(me); + multires_update_levels(me, 0); + + ++me->mr->level_count; + BLI_addtail(&me->mr->levels,lvl); + + /* Create vertices + =============== */ + lvl->totvert= lvl->prev->totvert + lvl->prev->totedge + lvl->prev->totface; + oldverts= me->mr->verts; + me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert, "multitres verts"); + /* Copy old verts */ + for(i=0; iprev->totvert; ++i) + me->mr->verts[i]= oldverts[i]; + /* Create new edge verts */ + for(i=0; iprev->totedge; ++i) { + VecMidf(me->mr->verts[lvl->prev->totvert + i].co, + oldverts[lvl->prev->edges[i].v[0]].co, + oldverts[lvl->prev->edges[i].v[1]].co); + lvl->prev->edges[i].mid= lvl->prev->totvert + i; + } + /* Create new face verts */ + for(i=0; iprev->totface; ++i) { + lvl->prev->faces[i].mid= lvl->prev->totvert + lvl->prev->totedge + i; + } + + multires_calc_temp_data(lvl->prev); + + /* Create faces + ============ */ + /* Allocate all the new faces (each triangle creates three, and + each quad creates four */ + lvl->totface= 0; + for(i=0; iprev->totface; ++i) + lvl->totface+= lvl->prev->faces[i].v[3] ? 4 : 3; + lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces"); + + curf= 0; + for(i=0; iprev->totface; ++i) { + const int max= lvl->prev->faces[i].v[3] ? 3 : 2; + + for(j=0; jfaces[curf].v[0]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev, + lvl->prev->faces[i].v[j], + lvl->prev->faces[i].v[j==0?max:j-1]); + lvl->faces[curf].v[1]= lvl->prev->faces[i].v[j]; + lvl->faces[curf].v[2]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev, + lvl->prev->faces[i].v[j], + lvl->prev->faces[i].v[j==max?0:j+1]); + lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i; + lvl->faces[curf].flag= lvl->prev->faces[i].flag; + lvl->faces[curf].mat_nr= lvl->prev->faces[i].mat_nr; + + ++curf; + } + } + + /* Create edges + ============ */ + /* Figure out how many edges to allocate */ + lvl->totedge= lvl->prev->totedge*2; + for(i=0; iprev->totface; ++i) + lvl->totedge+= lvl->prev->faces[i].v[3]?4:3; + lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges"); + + for(i=0; iprev->totedge; ++i) { + lvl->edges[i*2].v[0]= lvl->prev->edges[i].v[0]; + lvl->edges[i*2].v[1]= lvl->prev->edges[i].mid; + lvl->edges[i*2+1].v[0]= lvl->prev->edges[i].mid; + lvl->edges[i*2+1].v[1]= lvl->prev->edges[i].v[1]; + } + /* Add edges inside of old polygons */ + curf= 0; + cure= lvl->prev->totedge*2; + for(i=0; iprev->totface; ++i) { + for(j=0; j<(lvl->prev->faces[i].v[3]?4:3); ++j) { + lvl->edges[cure].v[0]= lvl->faces[curf].v[2]; + lvl->edges[cure].v[1]= lvl->faces[curf].v[3]; + ++cure; + ++curf; + } + } + + /* Smooth vertices + =============== */ + for(i=0; iprev->totface; ++i) { + const MultiresFace *f= &lvl->prev->faces[i]; + data.corner1= oldverts[f->v[0]].co; + data.corner2= oldverts[f->v[1]].co; + data.corner3= oldverts[f->v[2]].co; + data.corner4= oldverts[f->v[3]].co; + data.quad= f->v[3] ? 1 : 0; + multi_apply(me->mr->verts[f->mid].co, &data, 3, catmullclark_smooth_face); + } + + if(subdiv_type == 0) { + for(i=0; iprev->totedge; ++i) { + const MultiresEdge *e= &lvl->prev->edges[i]; + data.boundary= lvl->prev->edge_boundary_states[i]; + edge_face_neighbor_midpoints_accum(&data,lvl->prev, me->mr->verts, sizeof(MVert),e); + data.endpoint1= oldverts[e->v[0]].co; + data.endpoint2= oldverts[e->v[1]].co; + multi_apply(me->mr->verts[e->mid].co, &data, 3, catmullclark_smooth_edge); + } + + for(i=0; iprev->totvert; ++i) { + data.boundary= multires_vert_is_boundary(lvl->prev,i); + data.original= oldverts[i].co; + data.edge_count= BLI_countlist(&lvl->prev->vert_edge_map[i]); + if(data.boundary) + boundary_edges_average(&data,lvl->prev, oldverts, sizeof(MVert),i); + else { + vert_face_neighbor_midpoints_average(&data,lvl->prev, me->mr->verts, + sizeof(MVert),i); + vert_edge_neighbor_midpoints_average(&data,lvl->prev, oldverts, + sizeof(MVert),i); + } + multi_apply(me->mr->verts[i].co, &data, 3, catmullclark_smooth_vert); + } + } + + multires_free_temp_data(lvl->prev); + MEM_freeN(oldverts); + + /* Vertex Colors + ============= */ + curf= 0; + if(me->mr->use_col) { + MultiresColFace *cf= MEM_callocN(sizeof(MultiresColFace)*lvl->totface,"Multirescolfaces"); + lvl->colfaces= cf; + for(i=0; iprev->totface; ++i) { + const char sides= lvl->prev->faces[i].v[3]?4:3; + MultiresCol cntr; + + /* Find average color of 4 (or 3 for triangle) verts */ + multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides); + + for(j=0; jcol[0], + &lvl->prev->colfaces[i].col[j], + &lvl->prev->colfaces[i].col[j==0?sides-1:j-1]); + cf->col[1]= lvl->prev->colfaces[i].col[j]; + multires_col_avg2(&cf->col[2], + &lvl->prev->colfaces[i].col[j], + &lvl->prev->colfaces[i].col[j==sides-1?0:j+1]); + cf->col[3]= cntr; + + ++cf; + } + } + } + + me->mr->newlvl= me->mr->level_count; + me->mr->current= me->mr->newlvl; + /* Unless the render level has been set to something other than the + highest level (by the user), increment the render level to match + the highest available level */ + if(me->mr->renderlvl == me->mr->level_count - 1) me->mr->renderlvl= me->mr->level_count; + + multires_level_to_mesh(ob, me, 0); +} + +void multires_set_level(Object *ob, Mesh *me, const int render) +{ + if(me->pv) sculptmode_pmv_off(me); + + check_colors(me); + multires_update_levels(me, render); + + me->mr->current= me->mr->newlvl; + if(me->mr->current<1) me->mr->current= 1; + else if(me->mr->current>me->mr->level_count) me->mr->current= me->mr->level_count; + + multires_level_to_mesh(ob, me, render); +} + +/* Update the edge visibility flags to only show edges on or below the edgelvl */ +void multires_edge_level_update(Object *ob, Mesh *me) +{ + if(!G.obedit) { + MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); + MultiresLevel *edge_lvl= BLI_findlink(&me->mr->levels,me->mr->edgelvl-1); + const int threshold= edge_lvl->totedge * powf(2, me->mr->current - me->mr->edgelvl); + unsigned i; + + for(i=0; itotedge; ++i) { + const int ndx= me->pv ? me->pv->edge_map[i] : i; + if(ndx != -1) { /* -1= hidden edge */ + if(me->mr->edgelvl >= me->mr->current || imedge[ndx].flag |= ME_EDGEDRAW | ME_EDGERENDER; + else + me->medge[ndx].flag &= ~ME_EDGEDRAW & ~ME_EDGERENDER; + } + } + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a90914e6dcb..d30f0da95d6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -147,8 +147,6 @@ #include "BLO_undofile.h" #include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory -#include "multires.h" - #include "readfile.h" #include "genfile.h" diff --git a/source/blender/include/multires.h b/source/blender/include/multires.h index bfa765e62ef..54bba82b02d 100644 --- a/source/blender/include/multires.h +++ b/source/blender/include/multires.h @@ -43,39 +43,15 @@ struct uiBlock; int multires_test(); int multires_level1_test(); -struct MultiresLevel *multires_level_n(struct Multires *mr, int n); - void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned short cy); -void multires_disp_map(void *, void*); void multires_make(void *ob, void *me); void multires_delete(void *ob, void *me); -struct Multires *multires_copy(struct Multires *orig); -void multires_free(struct Multires *mr); -void multires_free_level(struct MultiresLevel *lvl); +void multires_subdivide(void *ob, void *me); void multires_del_lower(void *ob, void *me); void multires_del_higher(void *ob, void *me); -void multires_add_level(void *ob, void *me); void multires_set_level_cb(void *ob, void *me); -void multires_set_level(struct Object *ob, struct Mesh *me, const int render); -void multires_update_levels(struct Mesh *me, const int render); -void multires_level_to_mesh(struct Object *ob, struct Mesh *me, const int render); -void multires_edge_level_update(void *ob, void *me); +void multires_edge_level_update_cb(void *ob, void *me); int multires_modifier_warning(); -/* after adding or removing vcolor layers, run this */ -void multires_load_cols(Mesh *me); - -/* multires-firstlevel.c */ -/* Generic */ -void multires_update_first_level(struct Mesh *me, struct EditMesh *em); -void multires_update_customdata(struct MultiresLevel *lvl1, struct CustomData *src, - struct CustomData *dst, const int type); -void multires_customdata_to_mesh(struct Mesh *me, struct EditMesh *em, struct MultiresLevel *lvl, - struct CustomData *src, struct CustomData *dst, const int type); -void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl); - -void multires_add_layer(struct Mesh *me, struct CustomData *cd, const int type, const int n); -void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n); - #endif diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index 4424fd08ffd..8afbc75682a 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -1,5 +1,5 @@ /* - * $Id: Mesh.c 12892 2007-12-15 17:41:13Z joeedh $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -60,6 +60,7 @@ #include "BKE_mesh.h" #include "BKE_material.h" #include "BKE_main.h" +#include "BKE_multires.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index ca878933499..7da08378d56 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -89,6 +89,7 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_multires.h" #include "BKE_packedFile.h" #include "BKE_particle.h" #include "BKE_scene.h" @@ -5865,7 +5866,7 @@ void editing_panel_mesh_multires() uiBlockBeginAlign(block); but= uiDefBut(block,BUT,B_NOP,"Add Level", cx,cy,134,19,0,0,0,0,0,"Add a new level of subdivision at the end of the chain"); - uiButSetFunc(but,multires_add_level,ob,me); + uiButSetFunc(but, multires_subdivide, ob, me); uiDefButC(block, MENU, B_NOP, subsurfmenu, cx + 134, cy, 134, 19, &G.scene->toolsettings->multires_subdiv_type, 0, 0, 0, 0, "Selects type of subdivision algorithm."); cy-= 20; @@ -5881,7 +5882,7 @@ void editing_panel_mesh_multires() cy-= 20; but= uiDefButC(block,NUM,B_NOP,"Edges: ",cx,cy,268,19,(char *)&me->mr->edgelvl,1.0,me->mr->level_count,0,0,"Set level of edges to display"); - uiButSetFunc(but,multires_edge_level_update,ob,me); + uiButSetFunc(but,multires_edge_level_update_cb,ob,me); cy-= 20; uiBlockEndAlign(block); diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index be3d9429d31..33b9a60104f 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -63,6 +63,7 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_object.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -93,7 +94,6 @@ #include "mydevice.h" #include "blendef.h" #include "butspace.h" -#include "multires.h" #include "BSE_trans_types.h" diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 15f4e652490..6e0eb42aaf6 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -72,6 +72,7 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_object.h" #include "BKE_texture.h" #include "BKE_utildefines.h" diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index c563548759c..163417d9f08 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -117,6 +117,7 @@ #include "BKE_material.h" #include "BKE_mball.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_nla.h" #include "BKE_object.h" #include "BKE_particle.h" @@ -178,7 +179,6 @@ #include "blendef.h" #include "butspace.h" -#include "multires.h" #include "BIF_transform.h" #include "BIF_poseobject.h" diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c index 8704f9abfa4..69e2caaf12e 100644 --- a/source/blender/src/multires.c +++ b/source/blender/src/multires.c @@ -52,6 +52,7 @@ #include "BKE_key.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_multires.h" #include "BKE_object.h" #include "BIF_editmesh.h" @@ -78,8 +79,6 @@ #include -const CustomDataMask vdata_mask= CD_MASK_MDEFORMVERT; - void multires_calc_temp_data(struct MultiresLevel *lvl); int multires_test() @@ -109,24 +108,6 @@ void multires_check_state() sculptmode_correct_state(); } -typedef struct MultiresMapNode { - struct MultiresMapNode *next, *prev; - unsigned Index; -} MultiresMapNode; - -MultiresLevel *current_level(Multires *mr) -{ - return BLI_findlink(&mr->levels, mr->current - 1); -} - -MultiresLevel *multires_level_n(Multires *mr, int n) -{ - if(mr) - return BLI_findlink(&mr->levels, n - 1); - else - return NULL; -} - void Vec3fAvg3(float *out, float *v1, float *v2, float *v3) { out[0]= (v1[0]+v2[0]+v3[0])/3; @@ -140,376 +121,10 @@ void Vec3fAvg4(float *out, float *v1, float *v2, float *v3, float *v4) out[2]= (v1[2]+v2[2]+v3[2]+v4[2])/4; } -short multires_vert_is_boundary(MultiresLevel *lvl, unsigned v) -{ - MultiresMapNode *node= lvl->vert_edge_map[v].first; - while(node) { - if(lvl->edge_boundary_states[node->Index]) - return 1; - node= node->next; - } - return 0; -} - -typedef struct MultiApplyData { - /* Smooth faces */ - float *corner1, *corner2, *corner3, *corner4; - char quad; - - /* Smooth edges */ - char boundary; - float edge_face_neighbor_midpoints_accum[3]; - unsigned edge_face_neighbor_midpoints_total; - float *endpoint1, *endpoint2; - - /* Smooth verts */ - /* uses 'char boundary' */ - float *original; - int edge_count; - float vert_face_neighbor_midpoints_average[3]; - float vert_edge_neighbor_midpoints_average[3]; - float boundary_edges_average[3]; -} MultiApplyData; - -/* CATMULL-CLARK - ============= */ - -/* Simply averages the four corners of a polygon. */ -float catmullclark_smooth_face(MultiApplyData *data, const unsigned i) -{ - const float total= data->corner1[i]+data->corner2[i]+data->corner3[i]; - return data->quad ? (total+data->corner4[i])/4 : total/3; -} - -float catmullclark_smooth_edge(MultiApplyData *data, const unsigned i) -{ - float accum= 0; - unsigned count= 2; - - accum+= data->endpoint1[i] + data->endpoint2[i]; - - if(!data->boundary) { - accum+= data->edge_face_neighbor_midpoints_accum[i]; - count+= data->edge_face_neighbor_midpoints_total; - } - - return accum / count; -} -float catmullclark_smooth_vert(MultiApplyData *data, const unsigned i) -{ - if(data->boundary) { - return data->original[i]*0.75 + data->boundary_edges_average[i]*0.25; - } else { - return (data->vert_face_neighbor_midpoints_average[i] + - 2*data->vert_edge_neighbor_midpoints_average[i] + - data->original[i]*(data->edge_count-3))/data->edge_count; - } -} - - - -/* Call func count times, passing in[i] as the input and storing the output in out[i] */ -void multi_apply(float *out, MultiApplyData *data, - const unsigned count, float (*func)(MultiApplyData *, const unsigned)) -{ - unsigned i; - for(i=0; ivert_face_map[e->v[0]]; - ListBase *neighbors2= &lvl->vert_face_map[e->v[1]]; - MultiresMapNode *n1, *n2; - unsigned j,count= 0; - float *out= data->edge_face_neighbor_midpoints_accum; - - out[0]=out[1]=out[2]= 0; - - for(n1= neighbors1->first; n1; n1= n1->next) { - for(n2= neighbors2->first; n2; n2= n2->next) { - if(n1->Index == n2->Index) { - for(j=0; j<3; ++j) - out[j]+= GET_FLOAT(array,lvl->faces[n1->Index].mid,j,stride); - ++count; - } - } - } - - data->edge_face_neighbor_midpoints_total= count; -} -void vert_face_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl, - void *array, const char stride, const unsigned i) -{ - ListBase *neighbors= &lvl->vert_face_map[i]; - MultiresMapNode *n1; - unsigned j,count= 0; - float *out= data->vert_face_neighbor_midpoints_average; - - out[0]=out[1]=out[2]= 0; - - for(n1= neighbors->first; n1; n1= n1->next) { - for(j=0; j<3; ++j) - out[j]+= GET_FLOAT(array,lvl->faces[n1->Index].mid,j,stride); - ++count; - } - for(j=0; j<3; ++j) out[j]/= count; -} -void vert_edge_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl, - void *array, const char stride, const unsigned i) -{ - ListBase *neighbors= &lvl->vert_edge_map[i]; - MultiresMapNode *n1; - unsigned j,count= 0; - float *out= data->vert_edge_neighbor_midpoints_average; - - out[0]=out[1]=out[2]= 0; - - for(n1= neighbors->first; n1; n1= n1->next) { - for(j=0; j<3; ++j) - out[j]+= (GET_FLOAT(array,lvl->edges[n1->Index].v[0],j,stride) + - GET_FLOAT(array,lvl->edges[n1->Index].v[1],j,stride)) / 2; - ++count; - } - for(j=0; j<3; ++j) out[j]/= count; -} -void boundary_edges_average(MultiApplyData *data, MultiresLevel *lvl, - void *array, const char stride, const unsigned i) -{ - ListBase *neighbors= &lvl->vert_edge_map[i]; - MultiresMapNode *n1; - unsigned j,count= 0; - float *out= data->boundary_edges_average; - - out[0]=out[1]=out[2]= 0; - - for(n1= neighbors->first; n1; n1= n1->next) { - const MultiresEdge *e= &lvl->edges[n1->Index]; - const unsigned end= e->v[0]==i ? e->v[1] : e->v[0]; - - if(lvl->edge_boundary_states[n1->Index]) { - for(j=0; j<3; ++j) - out[j]+= GET_FLOAT(array,end,j,stride); - ++count; - } - } - for(j=0; j<3; ++j) out[j]/= count; -} - -/* For manipulating vertex colors / uvs */ -void mcol_to_multires(MultiresColFace *mrf, MCol *mcol) -{ - char i; - for(i=0; i<4; ++i) { - mrf->col[i].a= mcol[i].a; - mrf->col[i].r= mcol[i].r; - mrf->col[i].g= mcol[i].g; - mrf->col[i].b= mcol[i].b; - } -} - -float clamp_component(const float c) -{ - if(c<0) return 0; - else if(c>255) return 255; - else return c; -} - -void multires_to_mcol(MultiresColFace *f, MCol mcol[4]) -{ - unsigned char j; - for(j=0; j<4; ++j) { - mcol->a= clamp_component(f->col[j].a); - mcol->r= clamp_component(f->col[j].r); - mcol->g= clamp_component(f->col[j].g); - mcol->b= clamp_component(f->col[j].b); - ++mcol; - } -} - -/* 1 <= count <= 4 */ -void multires_col_avg(MultiresCol *avg, MultiresCol cols[4], char count) -{ - unsigned i; - avg->a= avg->r= avg->g= avg->b= 0; - for(i=0; ia+= cols[i].a; - avg->r+= cols[i].r; - avg->g+= cols[i].g; - avg->b+= cols[i].b; - } - avg->a/= count; - avg->r/= count; - avg->g/= count; - avg->b/= count; -} - -void multires_col_avg2(MultiresCol *avg, MultiresCol *c1, MultiresCol *c2) -{ - MultiresCol in[2]; - in[0]= *c1; - in[1]= *c2; - multires_col_avg(avg,in,2); -} - -void multires_load_cols(Mesh *me) -{ - MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *cur; - EditMesh *em= G.obedit ? G.editMesh : NULL; - CustomData *src= em ? &em->fdata : &me->fdata; - EditFace *efa= NULL; - unsigned i,j; - - if(!CustomData_has_layer(src, CD_MCOL) && !CustomData_has_layer(src, CD_MTFACE)) return; - - /* Add texcol data */ - for(cur= me->mr->levels.first; cur; cur= cur->next) - if(!cur->colfaces) - cur->colfaces= MEM_callocN(sizeof(MultiresColFace)*cur->totface,"ColFaces"); - - me->mr->use_col= CustomData_has_layer(src, CD_MCOL); - - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MultiresColFace *f= &lvl->colfaces[i]; - - if(me->mr->use_col) - mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]); - - if(em) efa= efa->next; - } - - /* Update higher levels */ - lvl= lvl->next; - while(lvl) { - MultiresColFace *cf= lvl->colfaces; - for(i=0; iprev->totface; ++i) { - const char sides= lvl->prev->faces[i].v[3]?4:3; - MultiresCol cntr; - - /* Find average color of 4 (or 3 for triangle) verts */ - multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides); - - for(j=0; jprev->colfaces[i]; - - multires_col_avg2(&cf->col[0], - &pf->col[j], - &pf->col[j==0?sides-1:j-1]); - cf->col[1]= pf->col[j]; - multires_col_avg2(&cf->col[2], - &pf->col[j], - &pf->col[j==sides-1?0:j+1]); - cf->col[3]= cntr; - - ++cf; - } - } - lvl= lvl->next; - } - - /* Update lower levels */ - lvl= me->mr->levels.last; - lvl= lvl->prev; - while(lvl) { - unsigned curf= 0; - for(i=0; itotface; ++i) { - MultiresFace *f= &lvl->faces[i]; - for(j=0; j<(f->v[3]?4:3); ++j) { - lvl->colfaces[i].col[j]= lvl->next->colfaces[curf].col[1]; - ++curf; - } - } - lvl= lvl->prev; - } -} - -void multires_get_vert(MVert *out, EditVert *eve, MVert *m, int i) -{ - if(eve) { - VecCopyf(out->co, eve->co); - out->flag= 0; - if(eve->f & SELECT) out->flag |= 1; - if(eve->h) out->flag |= ME_HIDE; - eve->tmp.l= i; - } - else - *out= *m; -} - -void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m) -{ - if(efa) { - MFace tmp; - int j; - tmp.v1= efa->v1->tmp.l; - tmp.v2= efa->v2->tmp.l; - tmp.v3= efa->v3->tmp.l; - tmp.v4= 0; - if(efa->v4) tmp.v4= efa->v4->tmp.l; - test_index_face(&tmp, NULL, 0, efa->v4?4:3); - for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j]; - - /* Flags */ - f->flag= efa->flag; - if(efa->f & 1) f->flag |= ME_FACE_SEL; - else f->flag &= ~ME_FACE_SEL; - if(efa->h) f->flag |= ME_HIDE; - f->mat_nr= efa->mat_nr; - } else { - f->v[0]= m->v1; - f->v[1]= m->v2; - f->v[2]= m->v3; - f->v[3]= m->v4; - f->flag= m->flag; - f->mat_nr= m->mat_nr; - } -} - -void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease) -{ - if(!eed || !flag) return; - - /* Would be nice if EditMesh edge flags could be unified with Mesh flags! */ - *flag= (eed->f & SELECT) | ME_EDGERENDER; - if(eed->f2<2) *flag |= ME_EDGEDRAW; - if(eed->f2==0) *flag |= ME_LOOSEEDGE; - if(eed->sharp) *flag |= ME_SHARP; - if(eed->seam) *flag |= ME_SEAM; - if(eed->h & EM_FGON) *flag |= ME_FGON; - if(eed->h & 1) *flag |= ME_HIDE; - - *crease= (char)(255.0*eed->crease); -} - -void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag, char *crease) -{ - if(eed) { - e->v[0]= eed->v1->tmp.l; - e->v[1]= eed->v2->tmp.l; - eed_to_medge_flag(eed, flag, crease); - } else { - e->v[0]= m->v1; - e->v[1]= m->v2; - *flag= m->flag; - *crease= m->crease; - } -} - void multires_make(void *ob, void *me_v) { Mesh *me= me_v; - MultiresLevel *lvl; - EditMesh *em= G.obedit ? G.editMesh : NULL; - EditVert *eve= NULL; - EditFace *efa= NULL; - EditEdge *eed= NULL; Key *key; - int i; /* Check for shape keys */ key= me->key; @@ -522,64 +137,14 @@ void multires_make(void *ob, void *me_v) return; } - lvl= MEM_callocN(sizeof(MultiresLevel), "multires level"); - waitcursor(1); multires_check_state(); - if(me->pv) sculptmode_pmv_off(me); - - me->mr= MEM_callocN(sizeof(Multires), "multires data"); - - BLI_addtail(&me->mr->levels,lvl); - me->mr->current= 1; - me->mr->level_count= 1; - me->mr->edgelvl= 1; - me->mr->pinlvl= 1; - me->mr->renderlvl= 1; - - /* Load mesh (or editmesh) into multires data */ - - /* Load vertices and vdata (MDeformVerts) */ - lvl->totvert= em ? BLI_countlist(&em->verts) : me->totvert; - me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts"); - multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata, - &me->mr->vdata, CD_MDEFORMVERT); - if(em) eve= em->verts.first; - for(i=0; itotvert; ++i) { - multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i); - if(em) eve= eve->next; - } - - /* Load faces and fdata (MTFaces) */ - lvl->totface= em ? BLI_countlist(&em->faces) : me->totface; - lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces"); - multires_update_customdata(me->mr->levels.first, em ? &em->fdata : &me->fdata, - &me->mr->fdata, CD_MTFACE); - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - multires_get_face(&lvl->faces[i], efa, &me->mface[i]); - if(em) efa= efa->next; - } - - /* Load edges and edge_flags */ - lvl->totedge= em ? BLI_countlist(&em->edges) : me->totedge; - lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges"); - me->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge flags"); - me->mr->edge_creases= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge creases"); - if(em) eed= em->edges.first; - for(i=0; itotedge; ++i) { - multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i], &me->mr->edge_creases[i]); - if(em) eed= eed->next; - } - - multires_load_cols(me); + multires_create(me); allqueue(REDRAWBUTSEDIT, 0); - BIF_undo_push("Make multires"); - waitcursor(0); } @@ -596,103 +161,6 @@ void multires_delete(void *ob, void *me_v) BIF_undo_push("Apply multires"); } -MultiresLevel *multires_level_copy(MultiresLevel *orig) -{ - if(orig) { - MultiresLevel *lvl= MEM_dupallocN(orig); - - lvl->next= lvl->prev= NULL; - lvl->faces= MEM_dupallocN(orig->faces); - lvl->colfaces= MEM_dupallocN(orig->colfaces); - lvl->edges= MEM_dupallocN(orig->edges); - lvl->edge_boundary_states = NULL; - lvl->vert_edge_map= lvl->vert_face_map= NULL; - lvl->map_mem= NULL; - - return lvl; - } - return NULL; -} - -Multires *multires_copy(Multires *orig) -{ - if(orig) { - Multires *mr= MEM_dupallocN(orig); - MultiresLevel *lvl; - - mr->levels.first= mr->levels.last= NULL; - - for(lvl= orig->levels.first; lvl; lvl= lvl->next) - BLI_addtail(&mr->levels, multires_level_copy(lvl)); - - mr->verts= MEM_dupallocN(orig->verts); - - lvl= mr->levels.first; - if(lvl) { - CustomData_copy(&orig->vdata, &mr->vdata, vdata_mask, CD_DUPLICATE, lvl->totvert); - CustomData_copy(&orig->fdata, &mr->fdata, CD_MASK_MTFACE, CD_DUPLICATE, lvl->totface); - mr->edge_flags= MEM_dupallocN(orig->edge_flags); - mr->edge_creases= MEM_dupallocN(orig->edge_creases); - } - - return mr; - } - return NULL; -} - -void multires_free(Multires *mr) -{ - if(mr) { - MultiresLevel* lvl= mr->levels.first; - - /* Free the first-level data */ - if(lvl) { - CustomData_free(&mr->vdata, lvl->totvert); - CustomData_free(&mr->fdata, lvl->totface); - MEM_freeN(mr->edge_flags); - MEM_freeN(mr->edge_creases); - } - - while(lvl) { - multires_free_level(lvl); - lvl= lvl->next; - } - - MEM_freeN(mr->verts); - - BLI_freelistN(&mr->levels); - - MEM_freeN(mr); - } -} - -/* Free and clear the temporary connectivity data */ -void multires_free_temp_data(MultiresLevel *lvl) -{ - if(lvl) { - if(lvl->edge_boundary_states) MEM_freeN(lvl->edge_boundary_states); - if(lvl->vert_edge_map) MEM_freeN(lvl->vert_edge_map); - if(lvl->vert_face_map) MEM_freeN(lvl->vert_face_map); - if(lvl->map_mem) MEM_freeN(lvl->map_mem); - - lvl->edge_boundary_states = NULL; - lvl->vert_edge_map = lvl->vert_face_map = NULL; - lvl->map_mem = NULL; - } -} - -/* Does not actually free lvl itself! */ -void multires_free_level(MultiresLevel *lvl) -{ - if(lvl) { - if(lvl->faces) MEM_freeN(lvl->faces); - if(lvl->edges) MEM_freeN(lvl->edges); - if(lvl->colfaces) MEM_freeN(lvl->colfaces); - - multires_free_temp_data(lvl); - } -} - /* Make sure that all level indices are clipped to [1, mr->level_count] */ void multires_clip_levels(Multires *mr) { @@ -789,426 +257,8 @@ void multires_del_higher(void *ob, void *me) BIF_undo_push("Multires delete higher"); } -unsigned int find_mid_edge(ListBase *vert_edge_map, - MultiresLevel *lvl, - const unsigned int v1, - const unsigned int v2 ) +static void multires_finish_mesh_update(Object *ob) { - MultiresMapNode *n= vert_edge_map[v1].first; - while(n) { - if(lvl->edges[n->Index].v[0]==v2 || - lvl->edges[n->Index].v[1]==v2) - return lvl->edges[n->Index].mid; - - n= n->next; - } - return -1; -} - -void check_colors(Mesh *me) -{ - CustomData *src= G.obedit ? &G.editMesh->fdata : &me->fdata; - const char col= CustomData_has_layer(src, CD_MCOL); - - /* Check if vertex colors have been deleted or added */ - if(me->mr->use_col && !col) - me->mr->use_col= 0; - else if(!me->mr->use_col && col) { - me->mr->use_col= 1; - multires_load_cols(me); - } -} - -void multires_add_level(void *ob, void *me_v) -{ - int i,j, curf, cure; - Mesh *me= me_v; - MultiresLevel *lvl= NULL; - MultiApplyData data; - MVert *oldverts= NULL; - - multires_check_state(); - - if(CustomData_number_of_layers(G.obedit ? &G.editMesh->fdata : &me->fdata, CD_MCOL) > 1) { - int ret= okee("Adding a level will delete all but the active vertex color layer, proceed?"); - if(!ret) - return; - } - - waitcursor(1); - - lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel"); - if(me->pv) sculptmode_pmv_off(me); - - check_colors(me); - multires_update_levels(me, 0); - - ++me->mr->level_count; - BLI_addtail(&me->mr->levels,lvl); - - /* Create vertices - =============== */ - lvl->totvert= lvl->prev->totvert + lvl->prev->totedge + lvl->prev->totface; - oldverts= me->mr->verts; - me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert, "multitres verts"); - /* Copy old verts */ - for(i=0; iprev->totvert; ++i) - me->mr->verts[i]= oldverts[i]; - /* Create new edge verts */ - for(i=0; iprev->totedge; ++i) { - VecMidf(me->mr->verts[lvl->prev->totvert + i].co, - oldverts[lvl->prev->edges[i].v[0]].co, - oldverts[lvl->prev->edges[i].v[1]].co); - lvl->prev->edges[i].mid= lvl->prev->totvert + i; - } - /* Create new face verts */ - for(i=0; iprev->totface; ++i) { - lvl->prev->faces[i].mid= lvl->prev->totvert + lvl->prev->totedge + i; - } - - multires_calc_temp_data(lvl->prev); - - /* Create faces - ============ */ - /* Allocate all the new faces (each triangle creates three, and - each quad creates four */ - lvl->totface= 0; - for(i=0; iprev->totface; ++i) - lvl->totface+= lvl->prev->faces[i].v[3] ? 4 : 3; - lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces"); - - curf= 0; - for(i=0; iprev->totface; ++i) { - const int max= lvl->prev->faces[i].v[3] ? 3 : 2; - - for(j=0; jfaces[curf].v[0]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev, - lvl->prev->faces[i].v[j], - lvl->prev->faces[i].v[j==0?max:j-1]); - lvl->faces[curf].v[1]= lvl->prev->faces[i].v[j]; - lvl->faces[curf].v[2]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev, - lvl->prev->faces[i].v[j], - lvl->prev->faces[i].v[j==max?0:j+1]); - lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i; - lvl->faces[curf].flag= lvl->prev->faces[i].flag; - lvl->faces[curf].mat_nr= lvl->prev->faces[i].mat_nr; - - ++curf; - } - } - - /* Create edges - ============ */ - /* Figure out how many edges to allocate */ - lvl->totedge= lvl->prev->totedge*2; - for(i=0; iprev->totface; ++i) - lvl->totedge+= lvl->prev->faces[i].v[3]?4:3; - lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges"); - - for(i=0; iprev->totedge; ++i) { - lvl->edges[i*2].v[0]= lvl->prev->edges[i].v[0]; - lvl->edges[i*2].v[1]= lvl->prev->edges[i].mid; - lvl->edges[i*2+1].v[0]= lvl->prev->edges[i].mid; - lvl->edges[i*2+1].v[1]= lvl->prev->edges[i].v[1]; - } - /* Add edges inside of old polygons */ - curf= 0; - cure= lvl->prev->totedge*2; - for(i=0; iprev->totface; ++i) { - for(j=0; j<(lvl->prev->faces[i].v[3]?4:3); ++j) { - lvl->edges[cure].v[0]= lvl->faces[curf].v[2]; - lvl->edges[cure].v[1]= lvl->faces[curf].v[3]; - ++cure; - ++curf; - } - } - - /* Smooth vertices - =============== */ - for(i=0; iprev->totface; ++i) { - const MultiresFace *f= &lvl->prev->faces[i]; - data.corner1= oldverts[f->v[0]].co; - data.corner2= oldverts[f->v[1]].co; - data.corner3= oldverts[f->v[2]].co; - data.corner4= oldverts[f->v[3]].co; - data.quad= f->v[3] ? 1 : 0; - multi_apply(me->mr->verts[f->mid].co, &data, 3, catmullclark_smooth_face); - } - - if(G.scene->toolsettings->multires_subdiv_type == 0) { - for(i=0; iprev->totedge; ++i) { - const MultiresEdge *e= &lvl->prev->edges[i]; - data.boundary= lvl->prev->edge_boundary_states[i]; - edge_face_neighbor_midpoints_accum(&data,lvl->prev, me->mr->verts, sizeof(MVert),e); - data.endpoint1= oldverts[e->v[0]].co; - data.endpoint2= oldverts[e->v[1]].co; - multi_apply(me->mr->verts[e->mid].co, &data, 3, catmullclark_smooth_edge); - } - - for(i=0; iprev->totvert; ++i) { - data.boundary= multires_vert_is_boundary(lvl->prev,i); - data.original= oldverts[i].co; - data.edge_count= BLI_countlist(&lvl->prev->vert_edge_map[i]); - if(data.boundary) - boundary_edges_average(&data,lvl->prev, oldverts, sizeof(MVert),i); - else { - vert_face_neighbor_midpoints_average(&data,lvl->prev, me->mr->verts, - sizeof(MVert),i); - vert_edge_neighbor_midpoints_average(&data,lvl->prev, oldverts, - sizeof(MVert),i); - } - multi_apply(me->mr->verts[i].co, &data, 3, catmullclark_smooth_vert); - } - } - - multires_free_temp_data(lvl->prev); - MEM_freeN(oldverts); - - /* Vertex Colors - ============= */ - curf= 0; - if(me->mr->use_col) { - MultiresColFace *cf= MEM_callocN(sizeof(MultiresColFace)*lvl->totface,"Multirescolfaces"); - lvl->colfaces= cf; - for(i=0; iprev->totface; ++i) { - const char sides= lvl->prev->faces[i].v[3]?4:3; - MultiresCol cntr; - - /* Find average color of 4 (or 3 for triangle) verts */ - multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides); - - for(j=0; jcol[0], - &lvl->prev->colfaces[i].col[j], - &lvl->prev->colfaces[i].col[j==0?sides-1:j-1]); - cf->col[1]= lvl->prev->colfaces[i].col[j]; - multires_col_avg2(&cf->col[2], - &lvl->prev->colfaces[i].col[j], - &lvl->prev->colfaces[i].col[j==sides-1?0:j+1]); - cf->col[3]= cntr; - - ++cf; - } - } - } - - me->mr->newlvl= me->mr->level_count; - me->mr->current= me->mr->newlvl; - /* Unless the render level has been set to something other than the - highest level (by the user), increment the render level to match - the highest available level */ - if(me->mr->renderlvl == me->mr->level_count - 1) me->mr->renderlvl= me->mr->level_count; - - multires_level_to_mesh(ob, me, 0); - - allqueue(REDRAWBUTSEDIT, 0); - - BIF_undo_push("Add multires level"); - - waitcursor(0); -} - -void multires_set_level_cb(void *ob, void *me) -{ - multires_set_level(ob, me, 0); -} - -void multires_set_level(struct Object *ob, struct Mesh *me, const int render) -{ - waitcursor(1); - - multires_check_state(); - - if(me->pv) sculptmode_pmv_off(me); - - check_colors(me); - multires_update_levels(me, render); - - me->mr->current= me->mr->newlvl; - if(me->mr->current<1) me->mr->current= 1; - else if(me->mr->current>me->mr->level_count) me->mr->current= me->mr->level_count; - - multires_level_to_mesh(ob, me, render); - - if(!render && (G.obedit || G.f & G_SCULPTMODE)) - BIF_undo_push("Multires set level"); - - allqueue(REDRAWBUTSEDIT, 0); - - waitcursor(0); -} - - -void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed) -{ - if(!eed) return; - - if(flag & ME_SEAM) eed->seam= 1; - if(flag & ME_SHARP) eed->sharp = 1; - if(flag & SELECT) eed->f |= SELECT; - if(flag & ME_FGON) eed->h= EM_FGON; - if(flag & ME_HIDE) eed->h |= 1; - - eed->crease= ((float)crease)/255.0; -} - -/* note, function is called in background render too, without UI */ -void multires_level_to_mesh(Object *ob, Mesh *me, const int render) -{ - MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - int i; - EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; - EditVert **eves= NULL; - EditEdge *eed= NULL; - - if(em) { - /* Remove editmesh elements */ - free_editMesh(em); - - eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers"); - } else { - CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); - CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); - CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface); - CustomData_free_layers(&me->fdata, CD_MCOL, me->totface); - - me->totvert= lvl->totvert; - me->totface= lvl->totface; - me->totedge= lvl->totedge; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - mesh_update_customdata_pointers(me); - } - - /* Vertices/Edges/Faces */ - - for(i=0; itotvert; ++i) { - if(em) { - eves[i]= addvertlist(me->mr->verts[i].co, NULL); - if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT; - if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1; - eves[i]->data= NULL; - } - else - me->mvert[i]= me->mr->verts[i]; - } - for(i=0; itotedge; ++i) { - if(em) { - addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL); - } else { - me->medge[i].v1= lvl->edges[i].v[0]; - me->medge[i].v2= lvl->edges[i].v[1]; - me->medge[i].flag &= ~ME_HIDE; - } - } - for(i=0; itotface; ++i) { - if(em) { - EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL; - EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]], - eves[lvl->faces[i].v[2]], eve4, NULL, NULL); - efa->flag= lvl->faces[i].flag & ~ME_HIDE; - efa->mat_nr= lvl->faces[i].mat_nr; - if(lvl->faces[i].flag & ME_FACE_SEL) - efa->f |= SELECT; - if(lvl->faces[i].flag & ME_HIDE) efa->h= 1; - efa->data= NULL; - } - else { - me->mface[i].v1= lvl->faces[i].v[0]; - me->mface[i].v2= lvl->faces[i].v[1]; - me->mface[i].v3= lvl->faces[i].v[2]; - me->mface[i].v4= lvl->faces[i].v[3]; - me->mface[i].flag= lvl->faces[i].flag; - me->mface[i].flag &= ~ME_HIDE; - me->mface[i].mat_nr= lvl->faces[i].mat_nr; - } - } - - /* Edge flags */ - if(em) eed= em->edges.first; - if(lvl==me->mr->levels.first) { - for(i=0; itotedge; ++i) { - if(em) { - medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed); - eed= eed->next; - } - else { - me->medge[i].flag= me->mr->edge_flags[i]; - me->medge[i].crease= me->mr->edge_creases[i]; - } - } - } else { - MultiresLevel *lvl1= me->mr->levels.first; - const int last= lvl1->totedge * pow(2, me->mr->current-1); - for(i=0; imr->current-1); - - if(em) { - medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed); - eed= eed->next; - } - else { - me->medge[i].flag= me->mr->edge_flags[ndx]; - me->medge[i].crease= me->mr->edge_creases[ndx]; - } - } - } - - if(em) { - eed= em->edges.first; - for(i=0, eed= em->edges.first; itotedge; ++i, eed= eed->next) { - eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE || - me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE; - } - } - - EM_select_flush(); - - multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT); - multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE); - - /* Colors */ - if(me->mr->use_col) { - MCol c[4]; - EditFace *efa= NULL; - CustomData *src= em ? &em->fdata : &me->fdata; - if(em) { - if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL); - efa= em->faces.first; - } - else { - if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface); - } - - for(i=0; itotface; ++i) { - if(em) { - if(me->mr->use_col) { - multires_to_mcol(&lvl->colfaces[i], c); - CustomData_em_set(src, efa->data, CD_MCOL, c); - } - efa= efa->next; - } - else if(me->mr->use_col) multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]); - } - - } - - mesh_update_customdata_pointers(me); - - if(em) { - MEM_freeN(eves); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - recalc_editnormals(); - } else { - multires_edge_level_update(ob,me); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); - } - /* friendly check for background render */ if(G.background==0) { object_handle_update(ob); @@ -1220,411 +270,48 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render) } } -void multires_update_colors(Mesh *me) +void multires_subdivide(void *ob_v, void *me_v) { - MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - MultiresCol *pr_deltas= NULL, *cr_deltas= NULL; - EditMesh *em= G.obedit ? G.editMesh : NULL; - CustomData *src= em ? &em->fdata : &me->fdata; - EditFace *efa= NULL; - unsigned i,j,curf= 0; + Mesh *me = me_v; + + multires_check_state(); + + if(CustomData_number_of_layers(G.obedit ? &G.editMesh->fdata : &me->fdata, CD_MCOL) > 1) { + int ret= okee("Adding a level will delete all but the active vertex color layer, proceed?"); + if(!ret) + return; + } + + waitcursor(1); + multires_add_level(ob_v, me, G.scene->toolsettings->multires_subdiv_type); + multires_finish_mesh_update(ob_v); + + allqueue(REDRAWBUTSEDIT, 0); + BIF_undo_push("Add multires level"); + waitcursor(0); +} + +void multires_set_level_cb(void *ob, void *me) +{ + waitcursor(1); - if(me->mr->use_col) { - /* Calc initial deltas */ - cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"initial color/uv deltas"); + multires_check_state(); - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MCol *col= em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]; - for(j=0; j<4; ++j) { - if(me->mr->use_col) { - cr_deltas[i*4+j].a= col[j].a - lvl->colfaces[i].col[j].a; - cr_deltas[i*4+j].r= col[j].r - lvl->colfaces[i].col[j].r; - cr_deltas[i*4+j].g= col[j].g - lvl->colfaces[i].col[j].g; - cr_deltas[i*4+j].b= col[j].b - lvl->colfaces[i].col[j].b; - } - } - if(em) efa= efa->next; - } - - /* Update current level */ - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MultiresColFace *f= &lvl->colfaces[i]; - - if(me->mr->use_col) - mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]); - - if(em) efa= efa->next; - } - - /* Update higher levels */ - lvl= lvl->next; - while(lvl) { - /* Set up new deltas, but keep the ones from the previous level */ - if(pr_deltas) MEM_freeN(pr_deltas); - pr_deltas= cr_deltas; - cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"color deltas"); - - curf= 0; - for(i=0; iprev->totface; ++i) { - const char sides= lvl->prev->faces[i].v[3]?4:3; - MultiresCol cntr; - - /* Find average color of 4 (or 3 for triangle) verts */ - multires_col_avg(&cntr,&pr_deltas[i*4],sides); - - for(j=0; jtotface; ++i) { - for(j=0; j<4; ++j) { - lvl->colfaces[i].col[j].a+= cr_deltas[i*4+j].a; - lvl->colfaces[i].col[j].r+= cr_deltas[i*4+j].r; - lvl->colfaces[i].col[j].g+= cr_deltas[i*4+j].g; - lvl->colfaces[i].col[j].b+= cr_deltas[i*4+j].b; - } - } - - lvl= lvl->next; - } - if(pr_deltas) MEM_freeN(pr_deltas); - if(cr_deltas) MEM_freeN(cr_deltas); - - /* Update lower levels */ - lvl= me->mr->levels.last; - lvl= lvl->prev; - while(lvl) { - MultiresColFace *nf= lvl->next->colfaces; - for(i=0; itotface; ++i) { - MultiresFace *f= &lvl->faces[i]; - for(j=0; j<(f->v[3]?4:3); ++j) { - lvl->colfaces[i].col[j]= nf->col[1]; - ++nf; - } - } - lvl= lvl->prev; - } - } -} - -/* Update vertex locations and vertex flags */ -void multires_update_vertices(Mesh *me, EditMesh *em) -{ - MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL, - *last_lvl= me->mr->levels.last; - vec3f *pr_deltas= NULL, *cr_deltas= NULL, *swap_deltas= NULL; - EditVert *eve= NULL; - MultiApplyData data; - int i, j; - - /* Prepare deltas */ - pr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 1"); - cr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 2"); - - /* Calculate initial deltas -- current mesh subtracted from current level*/ - if(em) eve= em->verts.first; - for(i=0; itotvert; ++i) { - if(em) { - VecSubf(&cr_deltas[i].x, eve->co, me->mr->verts[i].co); - eve= eve->next; - } else - VecSubf(&cr_deltas[i].x, me->mvert[i].co, me->mr->verts[i].co); - } - - - /* Copy current level's vertex flags and clear the rest */ - if(em) eve= em->verts.first; - for(i=0; i < last_lvl->totvert; ++i) { - if(i < cr_lvl->totvert) { - MVert mvflag; - multires_get_vert(&mvflag, eve, &me->mvert[i], i); - if(em) eve= eve->next; - me->mr->verts[i].flag= mvflag.flag; - } - else - me->mr->verts[i].flag= 0; - } - - /* If already on the highest level, copy current verts (including flags) into current level */ - if(cr_lvl == last_lvl) { - if(em) - eve= em->verts.first; - for(i=0; itotvert; ++i) { - multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i); - if(em) eve= eve->next; - } - } - - /* Update higher levels */ - pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - cr_lvl= pr_lvl->next; - while(cr_lvl) { - multires_calc_temp_data(pr_lvl); - - /* Swap the old/new deltas */ - swap_deltas= pr_deltas; - pr_deltas= cr_deltas; - cr_deltas= swap_deltas; - - /* Calculate and add new deltas - ============================ */ - for(i=0; itotface; ++i) { - const MultiresFace *f= &pr_lvl->faces[i]; - data.corner1= &pr_deltas[f->v[0]].x; - data.corner2= &pr_deltas[f->v[1]].x; - data.corner3= &pr_deltas[f->v[2]].x; - data.corner4= &pr_deltas[f->v[3]].x; - data.quad= f->v[3] ? 1 : 0; - multi_apply(&cr_deltas[f->mid].x, &data, 3, catmullclark_smooth_face); - - for(j=0; j<(data.quad?4:3); ++j) - me->mr->verts[f->mid].flag |= me->mr->verts[f->v[j]].flag; - } - - for(i=0; itotedge; ++i) { - const MultiresEdge *e= &pr_lvl->edges[i]; - data.boundary= pr_lvl->edge_boundary_states[i]; - edge_face_neighbor_midpoints_accum(&data,pr_lvl,cr_deltas,sizeof(vec3f),e); - data.endpoint1= &pr_deltas[e->v[0]].x; - data.endpoint2= &pr_deltas[e->v[1]].x; - multi_apply(&cr_deltas[e->mid].x, &data, 3, catmullclark_smooth_edge); - - for(j=0; j<2; ++j) - me->mr->verts[e->mid].flag |= me->mr->verts[e->v[j]].flag; - } - - for(i=0; itotvert; ++i) { - data.boundary= multires_vert_is_boundary(pr_lvl,i); - data.original= &pr_deltas[i].x; - data.edge_count= BLI_countlist(&pr_lvl->vert_edge_map[i]); - if(data.boundary) - boundary_edges_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i); - else { - vert_face_neighbor_midpoints_average(&data,pr_lvl,cr_deltas,sizeof(vec3f),i); - vert_edge_neighbor_midpoints_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i); - } - multi_apply(&cr_deltas[i].x, &data, 3, catmullclark_smooth_vert); - } - - /* Apply deltas to vertex locations */ - for(i=0; (cr_lvl == last_lvl) && (i < cr_lvl->totvert); ++i) { - VecAddf(me->mr->verts[i].co, - me->mr->verts[i].co, - &cr_deltas[i].x); - } - - multires_free_temp_data(pr_lvl); - - pr_lvl= pr_lvl->next; - cr_lvl= cr_lvl->next; - } - if(pr_deltas) MEM_freeN(pr_deltas); - if(cr_deltas) MEM_freeN(cr_deltas); - -} - -void multires_update_faces(Mesh *me, EditMesh *em) -{ - MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL, - *last_lvl= me->mr->levels.last; - char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *or_flag_damaged= NULL, - *pr_mat_damaged= NULL, *cr_mat_damaged= NULL, *or_mat_damaged= NULL, *swap= NULL; - EditFace *efa= NULL; - unsigned i,j,curf; - - /* Find for each face whether flag/mat has changed */ - pr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1"); - cr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1"); - pr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1"); - cr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1"); - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MultiresFace mftmp; - multires_get_face(&mftmp, efa, &me->mface[i]); - if(cr_lvl->faces[i].flag != mftmp.flag) - cr_flag_damaged[i]= 1; - if(cr_lvl->faces[i].mat_nr != mftmp.mat_nr) - cr_mat_damaged[i]= 1; - - /* Update current level */ - cr_lvl->faces[i].flag= mftmp.flag; - cr_lvl->faces[i].mat_nr= mftmp.mat_nr; - - if(em) efa= efa->next; - } - or_flag_damaged= MEM_dupallocN(cr_flag_damaged); - or_mat_damaged= MEM_dupallocN(cr_mat_damaged); - - /* Update lower levels */ - cr_lvl= cr_lvl->prev; - while(cr_lvl) { - swap= pr_flag_damaged; - pr_flag_damaged= cr_flag_damaged; - cr_flag_damaged= swap; - - swap= pr_mat_damaged; - pr_mat_damaged= cr_mat_damaged; - cr_mat_damaged= swap; - - curf= 0; - for(i=0; itotface; ++i) { - const int sides= cr_lvl->faces[i].v[3] ? 4 : 3; - - /* Check damages */ - for(j=0; jfaces[i].flag= cr_lvl->next->faces[curf].flag; - cr_flag_damaged[i]= 1; - } - if(pr_mat_damaged[curf]) { - cr_lvl->faces[i].mat_nr= cr_lvl->next->faces[curf].mat_nr; - cr_mat_damaged[i]= 1; - } - } - } - - cr_lvl= cr_lvl->prev; - } + multires_set_level(ob, me, 0); + multires_finish_mesh_update(ob); - /* Clear to original damages */ - if(cr_flag_damaged) MEM_freeN(cr_flag_damaged); - if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); - cr_flag_damaged= or_flag_damaged; - cr_mat_damaged= or_mat_damaged; + if(G.obedit || G.f & G_SCULPTMODE) + BIF_undo_push("Multires set level"); + + allqueue(REDRAWBUTSEDIT, 0); - /* Update higher levels */ - pr_lvl= current_level(me->mr); - cr_lvl= pr_lvl->next; - while(cr_lvl) { - swap= pr_flag_damaged; - pr_flag_damaged= cr_flag_damaged; - cr_flag_damaged= swap; - - swap= pr_mat_damaged; - pr_mat_damaged= cr_mat_damaged; - cr_mat_damaged= swap; - - /* Update faces */ - for(i=0, curf= 0; itotface; ++i) { - const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3; - for(j=0; jfaces[curf].flag= pr_lvl->faces[i].flag; - cr_flag_damaged[curf]= 1; - } - if(pr_mat_damaged[i]) { - cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr; - cr_mat_damaged[curf]= 1; - } - } - } - - pr_lvl= pr_lvl->next; - cr_lvl= cr_lvl->next; - } - - if(pr_flag_damaged) MEM_freeN(pr_flag_damaged); - if(cr_flag_damaged) MEM_freeN(cr_flag_damaged); - if(pr_mat_damaged) MEM_freeN(pr_mat_damaged); - if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); + waitcursor(0); } -void multires_update_levels(Mesh *me, const int render) +void multires_edge_level_update_cb(void *ob_v, void *me_v) { - EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; - - multires_update_first_level(me, em); - multires_update_vertices(me, em); - multires_update_faces(me, em); - multires_update_colors(me); -} - -void multires_calc_temp_data(MultiresLevel *lvl) -{ - unsigned i, j, emax; - MultiresMapNode *indexnode= NULL; - - lvl->map_mem= MEM_mallocN(sizeof(MultiresMapNode)*(lvl->totedge*2 + lvl->totface*4), "map_mem"); - indexnode= lvl->map_mem; - - /* edge map */ - lvl->vert_edge_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_edge_map"); - for(i=0; itotedge; ++i) { - for(j=0; j<2; ++j, ++indexnode) { - indexnode->Index= i; - BLI_addtail(&lvl->vert_edge_map[lvl->edges[i].v[j]], indexnode); - } - } - - /* face map */ - lvl->vert_face_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_face_map"); - for(i=0; itotface; ++i){ - for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j, ++indexnode) { - indexnode->Index= i; - BLI_addtail(&lvl->vert_face_map[lvl->faces[i].v[j]], indexnode); - } - } - - /* edge boundaries */ - emax = (lvl->prev ? (lvl->prev->totedge * 2) : lvl->totedge); - lvl->edge_boundary_states= MEM_callocN(sizeof(char)*lvl->totedge, "edge_boundary_states"); - for(i=0; ivert_face_map[lvl->edges[i].v[0]].first; - unsigned total= 0; - - lvl->edge_boundary_states[i] = 1; - while(n1 && lvl->edge_boundary_states[i] == 1) { - MultiresMapNode *n2= lvl->vert_face_map[lvl->edges[i].v[1]].first; - while(n2) { - if(n1->Index == n2->Index) { - ++total; - - if(total > 1) { - lvl->edge_boundary_states[i] = 0; - break; - } - } - - n2= n2->next; - } - n1= n1->next; - } - } -} - -void multires_edge_level_update(void *ob, void *me_v) -{ - if(!G.obedit) { - Mesh *me= me_v; - MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - MultiresLevel *edge_lvl= BLI_findlink(&me->mr->levels,me->mr->edgelvl-1); - const int threshold= edge_lvl->totedge * powf(2, me->mr->current - me->mr->edgelvl); - unsigned i; - - for(i=0; itotedge; ++i) { - const int ndx= me->pv ? me->pv->edge_map[i] : i; - if(ndx != -1) { /* -1= hidden edge */ - if(me->mr->edgelvl >= me->mr->current || imedge[ndx].flag |= ME_EDGEDRAW | ME_EDGERENDER; - else - me->medge[ndx].flag &= ~ME_EDGEDRAW & ~ME_EDGERENDER; - } - } - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); - } + multires_edge_level_update(ob_v, me_v); + allqueue(REDRAWVIEW3D, 0); } int multires_modifier_warning() diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 2e560b05228..a9c677342ae 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -86,6 +86,7 @@ #include "BKE_ipo.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_node.h" #include "BKE_scene.h" #include "BKE_texture.h" diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 4e1c6cd59a6..ac7ad0fa5fb 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -71,6 +71,7 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_multires.h" #include "BKE_object.h" #include "BKE_utildefines.h" From 9807586192768e3ead28cec626a2561e5d29b1d3 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 26 Dec 2007 10:43:51 +0000 Subject: [PATCH 49/99] == Multires == Fixed bad level calls within multires usage. --- source/blender/blenkernel/BKE_multires.h | 1 + source/blender/blenkernel/intern/multires.c | 167 +++++--------------- source/blender/include/multires.h | 1 + source/blender/python/api2_2x/Mesh.c | 2 +- source/blender/src/buttons_editing.c | 2 + source/blender/src/multires.c | 110 ++++++++++++- source/blender/src/space.c | 4 +- 7 files changed, 150 insertions(+), 137 deletions(-) diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 54bf801fd25..1335f250322 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -53,6 +53,7 @@ void multires_create(struct Mesh *me); void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n); void multires_add_layer(struct Mesh *me, struct CustomData *cd, const int type, const int n); void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl); +void multires_to_mcol(struct MultiresColFace *f, MCol mcol[4]); /* After adding or removing vcolor layers, run this */ void multires_load_cols(struct Mesh *me); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 2b50f37e7a1..2a9ac65b083 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -994,19 +994,6 @@ static unsigned int find_mid_edge(ListBase *vert_edge_map, return -1; } -static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed) -{ - if(!eed) return; - - if(flag & ME_SEAM) eed->seam= 1; - if(flag & ME_SHARP) eed->sharp = 1; - if(flag & SELECT) eed->f |= SELECT; - if(flag & ME_FGON) eed->h= EM_FGON; - if(flag & ME_HIDE) eed->h |= 1; - - eed->crease= ((float)crease)/255.0; -} - static float clamp_component(const float c) { if(c<0) return 0; @@ -1014,7 +1001,7 @@ static float clamp_component(const float c) else return c; } -static void multires_to_mcol(MultiresColFace *f, MCol mcol[4]) +void multires_to_mcol(MultiresColFace *f, MCol mcol[4]) { unsigned char j; for(j=0; j<4; ++j) { @@ -1031,88 +1018,51 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render) MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); int i; EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; - EditVert **eves= NULL; - EditEdge *eed= NULL; - if(em) { - /* Remove editmesh elements */ - free_editMesh(em); - - eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers"); - } else { - CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); - CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); - CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface); - CustomData_free_layers(&me->fdata, CD_MCOL, me->totface); - - me->totvert= lvl->totvert; - me->totface= lvl->totface; - me->totedge= lvl->totedge; + if(em) + return; - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - mesh_update_customdata_pointers(me); - } + CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); + CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); + CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface); + CustomData_free_layers(&me->fdata, CD_MCOL, me->totface); + + me->totvert= lvl->totvert; + me->totface= lvl->totface; + me->totedge= lvl->totedge; + + CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); + CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); + CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); + mesh_update_customdata_pointers(me); /* Vertices/Edges/Faces */ for(i=0; itotvert; ++i) { - if(em) { - eves[i]= addvertlist(me->mr->verts[i].co, NULL); - if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT; - if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1; - eves[i]->data= NULL; - } - else - me->mvert[i]= me->mr->verts[i]; + me->mvert[i]= me->mr->verts[i]; } for(i=0; itotedge; ++i) { - if(em) { - addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL); - } else { - me->medge[i].v1= lvl->edges[i].v[0]; - me->medge[i].v2= lvl->edges[i].v[1]; - me->medge[i].flag &= ~ME_HIDE; - } + me->medge[i].v1= lvl->edges[i].v[0]; + me->medge[i].v2= lvl->edges[i].v[1]; + me->medge[i].flag &= ~ME_HIDE; } for(i=0; itotface; ++i) { - if(em) { - EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL; - EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]], - eves[lvl->faces[i].v[2]], eve4, NULL, NULL); - efa->flag= lvl->faces[i].flag & ~ME_HIDE; - efa->mat_nr= lvl->faces[i].mat_nr; - if(lvl->faces[i].flag & ME_FACE_SEL) - efa->f |= SELECT; - if(lvl->faces[i].flag & ME_HIDE) efa->h= 1; - efa->data= NULL; - } - else { - me->mface[i].v1= lvl->faces[i].v[0]; - me->mface[i].v2= lvl->faces[i].v[1]; - me->mface[i].v3= lvl->faces[i].v[2]; - me->mface[i].v4= lvl->faces[i].v[3]; - me->mface[i].flag= lvl->faces[i].flag; - me->mface[i].flag &= ~ME_HIDE; - me->mface[i].mat_nr= lvl->faces[i].mat_nr; - } + me->mface[i].v1= lvl->faces[i].v[0]; + me->mface[i].v2= lvl->faces[i].v[1]; + me->mface[i].v3= lvl->faces[i].v[2]; + me->mface[i].v4= lvl->faces[i].v[3]; + me->mface[i].flag= lvl->faces[i].flag; + me->mface[i].flag &= ~ME_HIDE; + me->mface[i].mat_nr= lvl->faces[i].mat_nr; } /* Edge flags */ - if(em) eed= em->edges.first; if(lvl==me->mr->levels.first) { for(i=0; itotedge; ++i) { - if(em) { - medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed); - eed= eed->next; - } - else { - me->medge[i].flag= me->mr->edge_flags[i]; - me->medge[i].crease= me->mr->edge_creases[i]; - } + me->medge[i].flag= me->mr->edge_flags[i]; + me->medge[i].crease= me->mr->edge_creases[i]; } } else { MultiresLevel *lvl1= me->mr->levels.first; @@ -1120,67 +1070,32 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render) for(i=0; imr->current-1); - if(em) { - medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed); - eed= eed->next; - } - else { - me->medge[i].flag= me->mr->edge_flags[ndx]; - me->medge[i].crease= me->mr->edge_creases[ndx]; - } + me->medge[i].flag= me->mr->edge_flags[ndx]; + me->medge[i].crease= me->mr->edge_creases[ndx]; } } - if(em) { - eed= em->edges.first; - for(i=0, eed= em->edges.first; itotedge; ++i, eed= eed->next) { - eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE || - me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE; - } - } - - EM_select_flush(); - multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT); multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE); /* Colors */ if(me->mr->use_col) { - MCol c[4]; - EditFace *efa= NULL; - CustomData *src= em ? &em->fdata : &me->fdata; - if(em) { - if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL); - efa= em->faces.first; - } - else { - if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface); - } + CustomData *src= &me->fdata; + + if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface); for(i=0; itotface; ++i) { - if(em) { - if(me->mr->use_col) { - multires_to_mcol(&lvl->colfaces[i], c); - CustomData_em_set(src, efa->data, CD_MCOL, c); - } - efa= efa->next; - } - else if(me->mr->use_col) multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]); + if(me->mr->use_col) + multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]); } } mesh_update_customdata_pointers(me); - if(em) { - MEM_freeN(eves); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - recalc_editnormals(); - } else { - multires_edge_level_update(ob,me); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); - } + multires_edge_level_update(ob,me); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); } void multires_add_level(Object *ob, Mesh *me, const char subdiv_type) diff --git a/source/blender/include/multires.h b/source/blender/include/multires.h index 54bba82b02d..7d0bed47d53 100644 --- a/source/blender/include/multires.h +++ b/source/blender/include/multires.h @@ -47,6 +47,7 @@ void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned void multires_make(void *ob, void *me); void multires_delete(void *ob, void *me); +void multires_level_to_editmesh(struct Object *ob, struct Mesh *me, const int render); void multires_subdivide(void *ob, void *me); void multires_del_lower(void *ob, void *me); void multires_del_higher(void *ob, void *me); diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index 8afbc75682a..69975ed611e 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -7161,7 +7161,7 @@ static int Mesh_setMultires( BPy_Mesh * self, PyObject *value, void *type ) switch ((int)type) { case MESH_MULTIRES_LEVEL: self->mesh->mr->newlvl = i; - multires_set_level(self->object, self->mesh, 0); + multires_set_level_cb(self->object, self->mesh); break; case MESH_MULTIRES_EDGE: self->mesh->mr->edgelvl = i; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 7da08378d56..d74f045255d 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -737,6 +737,7 @@ static void delete_customdata_layer(void *data1, void *data2) from the data stored in multires */ if(me && me->mr) { multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]); + multires_level_to_editmesh(OBACT, me, 0); } else if(G.obedit) { EM_free_data_layer(data, type); @@ -4468,6 +4469,7 @@ void do_meshbuts(unsigned short event) if(me && me->mr) { multires_add_layer(me, &me->mr->fdata, CD_MTFACE, layernum); + multires_level_to_editmesh(ob, me, 0); } else if(G.obedit) { EM_add_data_layer(&em->fdata, CD_MTFACE); diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c index 69e2caaf12e..56bfad4e4db 100644 --- a/source/blender/src/multires.c +++ b/source/blender/src/multires.c @@ -108,17 +108,109 @@ void multires_check_state() sculptmode_correct_state(); } -void Vec3fAvg3(float *out, float *v1, float *v2, float *v3) +static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed) { - out[0]= (v1[0]+v2[0]+v3[0])/3; - out[1]= (v1[1]+v2[1]+v3[1])/3; - out[2]= (v1[2]+v2[2]+v3[2])/3; + if(!eed) return; + + if(flag & ME_SEAM) eed->seam= 1; + if(flag & ME_SHARP) eed->sharp = 1; + if(flag & SELECT) eed->f |= SELECT; + if(flag & ME_FGON) eed->h= EM_FGON; + if(flag & ME_HIDE) eed->h |= 1; + + eed->crease= ((float)crease)/255.0; } -void Vec3fAvg4(float *out, float *v1, float *v2, float *v3, float *v4) + +void multires_level_to_editmesh(Object *ob, Mesh *me, const int render) { - out[0]= (v1[0]+v2[0]+v3[0]+v4[0])/4; - out[1]= (v1[1]+v2[1]+v3[1]+v4[1])/4; - out[2]= (v1[2]+v2[2]+v3[2]+v4[2])/4; + MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); + int i; + EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; + EditVert **eves= NULL; + EditEdge *eed= NULL; + + if(em) { + /* Remove editmesh elements */ + free_editMesh(em); + + eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers"); + + /* Vertices/Edges/Faces */ + for(i=0; itotvert; ++i) { + eves[i]= addvertlist(me->mr->verts[i].co, NULL); + if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT; + if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1; + eves[i]->data= NULL; + } + for(i=0; itotedge; ++i) { + addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL); + } + for(i=0; itotface; ++i) { + EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL; + EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]], + eves[lvl->faces[i].v[2]], eve4, NULL, NULL); + efa->flag= lvl->faces[i].flag & ~ME_HIDE; + efa->mat_nr= lvl->faces[i].mat_nr; + if(lvl->faces[i].flag & ME_FACE_SEL) + efa->f |= SELECT; + if(lvl->faces[i].flag & ME_HIDE) efa->h= 1; + efa->data= NULL; + } + + /* Edge flags */ + eed= em->edges.first; + if(lvl==me->mr->levels.first) { + for(i=0; itotedge; ++i) { + medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed); + eed= eed->next; + } + } else { + MultiresLevel *lvl1= me->mr->levels.first; + const int last= lvl1->totedge * pow(2, me->mr->current-1); + for(i=0; imr->current-1); + + medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed); + eed= eed->next; + } + } + + eed= em->edges.first; + for(i=0, eed= em->edges.first; itotedge; ++i, eed= eed->next) { + eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE || + me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE; + } + + EM_select_flush(); + + multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT); + multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE); + + /* Colors */ + if(me->mr->use_col) { + MCol c[4]; + EditFace *efa= NULL; + CustomData *src= &em->fdata; + + if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL); + efa= em->faces.first; + + for(i=0; itotface; ++i) { + if(me->mr->use_col) { + multires_to_mcol(&lvl->colfaces[i], c); + CustomData_em_set(src, efa->data, CD_MCOL, c); + } + efa= efa->next; + } + + } + + mesh_update_customdata_pointers(me); + + MEM_freeN(eves); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + recalc_editnormals(); + } } void multires_make(void *ob, void *me_v) @@ -284,6 +376,7 @@ void multires_subdivide(void *ob_v, void *me_v) waitcursor(1); multires_add_level(ob_v, me, G.scene->toolsettings->multires_subdiv_type); + multires_level_to_editmesh(ob_v, me, 0); multires_finish_mesh_update(ob_v); allqueue(REDRAWBUTSEDIT, 0); @@ -298,6 +391,7 @@ void multires_set_level_cb(void *ob, void *me) multires_check_state(); multires_set_level(ob, me, 0); + multires_level_to_editmesh(ob, me, 0); multires_finish_mesh_update(ob); if(G.obedit || G.f & G_SCULPTMODE) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index a9c677342ae..72107ec7003 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1495,13 +1495,13 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) case PAGEUPKEY: if(me && me->mr) { me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1; - multires_set_level(ob, ob->data, 0); + multires_set_level_cb(ob, ob->data); } break; case PAGEDOWNKEY: if(me && me->mr) { me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1; - multires_set_level(ob, ob->data, 0); + multires_set_level_cb(ob, ob->data); } break; /* Partial Visibility */ From f81bc543e7f274aa88ca0d0c00dc86b4d6381416 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 26 Dec 2007 10:59:08 +0000 Subject: [PATCH 50/99] =Scons ffmpeg link order update= Update link order for ffmpeg on win32, patch provided by Anders Nor "Debolaz" Berle on irc. --- config/win32-mingw-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 8f8c30d46b0..8c8c12db46f 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -18,7 +18,7 @@ BF_OPENAL_LIB = 'openal_static' BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' WITH_BF_FFMPEG = 'false' -BF_FFMPEG_LIB = 'xvidcore x264 avutil avformat avutil swscale avcodec avutil xvidcore x264' +BF_FFMPEG_LIB = 'avformat swscale avcodec avutil xvidcore x264' BF_FFMPEG_LIBPATH = LIBDIR + '/gcc/ffmpeg/lib' BF_FFMPEG_INC = LIBDIR + '/gcc/ffmpeg/include' From 10b8237eab7e41ef7563cedbf6a2e4e5dda13456 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 26 Dec 2007 11:17:26 +0000 Subject: [PATCH 51/99] == PoseLib - Pose-Library Tool for Blender == "A slightly late Christmas present for the Animators out there :-)" This tool allows animators to store frequently used poses in an action, and be able to label those poses to help them retrieve them later. In a way, it acts as a glorified clipboard for poses. One of the cool features with this is the ability to select which stored pose to use interactively in the 3d-view. Once a few poses have been stored in the PoseLib, simply use the "Ctrl L" hotkey to start previewing. Use the Mousewheel or the Page Up/Down keys to change poses, and confirm/cancel the preview in the same way as you do for transforms. Usage Notes: * Each Armature may get its own PoseLib. PoseLibs are simply actions with extra data, so they can get relinked. * Manually editing actions used as PoseLibs is not a good idea, as some data may not be able to be found. Tools to automagically find poses in an action could be investigated... * PoseLib will only apply/retrieve poses to/from selected bones * A basic UI for this can be found in the "Links and Materials" panel. Most of the PoseLib tools are presented there. Useful Hotkeys (also found in Pose->PoseLib menu): * Ctrl L - interactively preview poses * Shift L - add a new pose or replace an existing pose in the PoseLib with the current pose * Ctrl Shift L - rename an existing pose in the PoseLib * Alt L - remove a pose from the poselib.c --- source/blender/blenkernel/intern/action.c | 12 + source/blender/blenkernel/intern/object.c | 1 + source/blender/blenloader/intern/readfile.c | 15 +- source/blender/blenloader/intern/writefile.c | 12 +- source/blender/include/BIF_poselib.h | 52 ++ source/blender/include/butspace.h | 5 + source/blender/makesdna/DNA_action_types.h | 24 + source/blender/src/buttons_editing.c | 80 ++ source/blender/src/header_view3d.c | 45 ++ source/blender/src/poselib.c | 770 +++++++++++++++++++ source/blender/src/space.c | 12 +- 11 files changed, 1022 insertions(+), 6 deletions(-) create mode 100644 source/blender/include/BIF_poselib.h create mode 100644 source/blender/src/poselib.c diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 162ee582d74..86e119f5e6f 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -163,6 +163,15 @@ void make_local_action(bAction *act) } } +static void free_act_poselib (bAction *act) +{ + if (act->poselib) { + bPoseLib *pl= act->poselib; + + BLI_freelistN(&pl->poses); + MEM_freeN(pl); + } +} void free_action (bAction *act) { @@ -177,6 +186,9 @@ void free_action (bAction *act) if (act->chanbase.first) BLI_freelistN(&act->chanbase); + + /* Free PoseLib */ + free_act_poselib(act); } bAction *copy_action (bAction *src) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d48be54fe10..b4512f3b1b3 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -230,6 +230,7 @@ void free_object(Object *ob) BLI_freelistN(&ob->defbase); if(ob->pose) { free_pose_channels(ob->pose); + if (ob->pose->poselib) ob->pose->poselib->id.us--; MEM_freeN(ob->pose); } free_effects(&ob->effect); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d30f0da95d6..f8f0395300c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1785,6 +1785,9 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose) } } + // ob->id.lib??? + pose->poselib = newlibadr_us(fd, ob->id.lib, pose->poselib); + if(rebuild) { ob->recalc= OB_RECALC; pose->flag |= POSE_RECALC; @@ -1814,12 +1817,12 @@ static void lib_link_action(FileData *fd, Main *main) while(act) { if(act->id.flag & LIB_NEEDLINK) { act->id.flag -= LIB_NEEDLINK; - + for (chan=act->chanbase.first; chan; chan=chan->next) { chan->ipo= newlibadr_us(fd, act->id.lib, chan->ipo); lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels); } - + } act= act->id.next; } @@ -1847,7 +1850,10 @@ static void direct_link_action(FileData *fd, bAction *act) for (achan = act->chanbase.first; achan; achan=achan->next) link_list(fd, &achan->constraintChannels); - + + act->poselib= newdataadr(fd, act->poselib); + if (act->poselib) + link_list(fd, &act->poselib->poses); } static void direct_link_armature(FileData *fd, bArmature *arm) @@ -2942,7 +2948,6 @@ static void direct_link_pose(FileData *fd, bPose *pose) { pchan->iktree.first= pchan->iktree.last= NULL; pchan->path= NULL; } - } static void direct_link_modifiers(FileData *fd, ListBase *lb) @@ -7799,6 +7804,8 @@ static void expand_pose(FileData *fd, Main *mainvar, bPose *pose) expand_constraints(fd, mainvar, &chan->constraints); expand_doit(fd, mainvar, chan->custom); } + + expand_doit(fd, mainvar, pose->poselib); } static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 2e14fe55383..90f48868911 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1743,11 +1743,21 @@ static void write_actions(WriteData *wd, ListBase *idbase) if (act->id.us>0 || wd->current) { writestruct(wd, ID_AC, "bAction", 1, act); if (act->id.properties) IDP_WriteProperty(act->id.properties, wd); - + for (chan=act->chanbase.first; chan; chan=chan->next) { writestruct(wd, DATA, "bActionChannel", 1, chan); write_constraint_channels(wd, &chan->constraintChannels); } + + if (act->poselib) { + bPoseLib *pl= act->poselib; + bPoseLibRef *plr; + + writestruct(wd, DATA, "bPoseLib", 1, pl); + + for (plr= pl->poses.first; plr; plr= plr->next) + writestruct(wd, DATA, "bPoseLibRef", 1, plr); + } } } } diff --git a/source/blender/include/BIF_poselib.h b/source/blender/include/BIF_poselib.h new file mode 100644 index 00000000000..213714cf09a --- /dev/null +++ b/source/blender/include/BIF_poselib.h @@ -0,0 +1,52 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation + * All rights reserved. + * + * The Original Code is: this is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BIF_POSELIB_H +#define BIF_POSELIB_H + +struct Object; +struct bPoseLib; +struct bPoseLibRef; + +char *poselib_build_poses_menu(struct bPoseLib *pl, char title[]); +void poselib_unique_pose_name(struct bPoseLib *pl, char name[]); +int poselib_get_free_index(struct bPoseLib *pl); + +struct bPoseLib *poselib_init_new(struct Object *ob); + +void poselib_remove_pose(struct Object *ob, struct bPoseLibRef *plr); +void poselib_rename_pose(struct Object *ob); +void poselib_add_current_pose(struct Object *ob, int mode); + +void poselib_preview_poses(struct Object *ob); + +#endif diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index ec8ffb819f6..7b6213be38f 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -501,6 +501,11 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_ARM_CALCPATHS 2303 #define B_ARM_CLEARPATHS 2304 +#define B_POSELIB_NEW 2310 +#define B_POSELIB_ADDPOSE 2311 +#define B_POSELIB_REPLACEP 2312 +#define B_POSELIB_REMOVEP 2313 + /* *********************** */ #define B_CAMBUTS 2500 diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index db6a2bda53c..9921d784984 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -90,12 +90,35 @@ typedef struct bPoseChannel { */ typedef struct bPose { ListBase chanbase; /* list of pose channels */ + struct bAction *poselib; /* poselib-action for this pose */ + short flag, proxy_layer; /* proxy layer: copy from armature, gets synced */ + float ctime; /* local action time of this pose */ float stride_offset[3]; /* applied to object */ float cyclic_offset[3]; /* result of match and cycles, applied in where_is_pose() */ } bPose; + +/* "Pose" reference for PoseLib */ +typedef struct bPoseLibRef { + struct bPoseLibRef *next, *prev; + int frame; /* frame in the action to look for this pose */ + char name[32]; /* name of the pose */ + int pad; +} bPoseLibRef; + +/* PoseLib data for Action + * PoseLib data is stored in actions so that poselibs can easily be assigned/removed from + * a pose. Currently the only data that is stored for a poselib is a set of references to which + * frame a named pose occurs in the action. + */ +typedef struct bPoseLib { + ListBase poses; /* List of poses for an action (arranged in chronological order) */ + int flag; /* Settings (not used yet) */ + int active_nr; /* Index of the poselib's active pose (for UI) */ +} bPoseLib; + /* Action Channels belong to Actions. They are linked with an IPO block, and can also own * Constraint Channels in certain situations. */ @@ -115,6 +138,7 @@ typedef struct bActionChannel { typedef struct bAction { ID id; ListBase chanbase; /* Action Channels in this Action */ + bPoseLib *poselib; /* PoseLib data of this Action (only if the action is used as poselib) */ } bAction; /* Action Editor Space. This is defined here instead of in DNA_space_types.h */ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index d74f045255d..0cc3a70d2d1 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -114,6 +114,7 @@ #include "BIF_interface.h" #include "BIF_meshtools.h" #include "BIF_mywindow.h" +#include "BIF_poselib.h" #include "BIF_poseobject.h" #include "BIF_renderwin.h" #include "BIF_resources.h" @@ -3729,6 +3730,32 @@ void do_armbuts(unsigned short event) if (ob && ob->pose) pose_clear_paths(ob); break; + + case B_POSELIB_NEW: + if (ob && ob->pose) + poselib_init_new(ob); + allqueue(REDRAWBUTSEDIT, 0); + break; + case B_POSELIB_ADDPOSE: + if (ob && ob->pose) + poselib_add_current_pose(ob, 1); + allqueue(REDRAWBUTSEDIT, 0); + break; + case B_POSELIB_REPLACEP: + if (ob && ob->pose) + poselib_add_current_pose(ob, 2); + allqueue(REDRAWBUTSEDIT, 0); + break; + case B_POSELIB_REMOVEP: + if (ob && ob->pose) { + bAction *act= ob->pose->poselib; + bPoseLib *pl= act->poselib; + bPoseLibRef *plr= BLI_findlink(&pl->poses, pl->active_nr-1); + + poselib_remove_pose(ob, plr); + } + allqueue(REDRAWBUTSEDIT, 0); + break; } } @@ -4937,6 +4964,59 @@ static void editing_panel_links(Object *ob) return; } + /* poselib for armatures */ + if (ob->type==OB_ARMATURE) { + if ((ob->pose) && (ob->flag & OB_POSEMODE) && (G.obedit != ob)) { + bPose *pose= ob->pose; + bAction *act= pose->poselib; + + xco= 143; + + uiDefBut(block, LABEL,0,"PoseLib:", xco, 154, 130,20, 0, 0, 0, 0, 0, ""); + + /* PoseLib Action */ + if (act) { + if (act->poselib==NULL) { + uiBlockSetCol(block, TH_REDALERT); + uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, REDRAWBUTSEDIT, "AC:", xco, 130, 140, 20, &pose->poselib, "Action to use as PoseLib - (Warning: this Action doesn't have a PoseLib)"); + uiBlockSetCol(block, TH_AUTO); + } + else { + uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, REDRAWBUTSEDIT, "AC:", xco, 130, 140, 20, &pose->poselib, "Action to use as PoseLib"); + } + } + uiDefBut(block, BUT, B_POSELIB_NEW, "New PoseLib", xco,110,140,20, 0, 0, 0, 0, 0, "Creates a new PoseLib"); + + + /* poselib pose editing controls */ + if ((act) && (act->poselib)) { + bPoseLib *pl= act->poselib; + bPoseLibRef *plr= BLI_findlink(&pl->poses, pl->active_nr-1); + int plr_count= BLI_countlist(&pl->poses); + char *menustr= poselib_build_poses_menu(pl, "PoseLib Poses"); + + uiBlockBeginAlign(block); + /* currently 'active' pose */ + uiDefButI(block, MENU, REDRAWBUTSEDIT, menustr, xco, 85,18,20, &pl->active_nr, 1, plr_count, 0, 0, "Browses Poses in PoseLib"); + MEM_freeN(menustr); + + if (pl->active_nr) { + but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", 161,85,140-18-20,20, plr->name, 0, 31, 0, 0, "Displays current PoseLib Pose name. Click to change."); + //uiButSetFunc(but, verify_vertexgroup_name_func, defGroup, NULL); + //uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); + + but = uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, 263, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this PoseLib Pose from PoseLib"); + } + + /* add new poses */ + uiDefBut(block, BUT, B_POSELIB_ADDPOSE, "Add Pose", xco,65,70,20, 0, 0, 0, 0, 0, "Add current pose to PoseLib"); + uiDefBut(block, BUT, B_POSELIB_REPLACEP, "Replace Pose", xco+70,65,70,20, 0, 0, 0, 0, 0, "Replace existing PoseLib Pose with current pose"); + uiBlockEndAlign(block); + } + } + return; + } + /* vertex group... partially editmode... */ if(ob->type==OB_MESH || ob->type==OB_LATTICE) { bDeformGroup *defGroup; diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 95f24c34098..55740861998 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -111,6 +111,7 @@ #include "BIF_interface.h" #include "BIF_mainqueue.h" #include "BIF_meshtools.h" +#include "BIF_poselib.h" #include "BIF_poseobject.h" #include "BIF_renderwin.h" #include "BIF_resources.h" @@ -4048,6 +4049,49 @@ static uiBlock *view3d_pose_armature_motionpathsmenu(void *arg_unused) return block; } +static void do_view3d_pose_armature_poselibmenu(void *arg, int event) +{ + Object *ob= OBACT; + + switch(event) { + case 1: + poselib_preview_poses(ob); + break; + case 2: + poselib_add_current_pose(ob, 0); + break; + case 3: + poselib_rename_pose(ob); + break; + case 4: + poselib_remove_pose(ob, NULL); + break; + } + + allqueue(REDRAWVIEW3D, 0); +} + +static uiBlock *view3d_pose_armature_poselibmenu(void *arg_unused) +{ + uiBlock *block; + short yco = 20, menuwidth = 120; + + block= uiNewBlock(&curarea->uiblocks, "view3d_pose_armature_poselibmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_view3d_pose_armature_poselibmenu, NULL); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Pose|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add/Replace Pose|Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename Pose|Ctrl Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Pose|Alt L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); + + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block, 60); + return block; +} + static void do_view3d_pose_armaturemenu(void *arg, int event) { Object *ob; @@ -4126,6 +4170,7 @@ static uiBlock *view3d_pose_armaturemenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBlockBut(block, view3d_pose_armature_poselibmenu, NULL, ICON_RIGHTARROW_THIN, "PoseLib", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, view3d_pose_armature_motionpathsmenu, NULL, ICON_RIGHTARROW_THIN, "Motion Paths", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, view3d_pose_armature_ikmenu, NULL, ICON_RIGHTARROW_THIN, "Inverse Kinematics", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, view3d_pose_armature_constraintsmenu, NULL, ICON_RIGHTARROW_THIN, "Constraints", 0, yco-=20, 120, 19, ""); diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c new file mode 100644 index 00000000000..6e088bbf03e --- /dev/null +++ b/source/blender/src/poselib.c @@ -0,0 +1,770 @@ + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_dynstr.h" + +#include "DNA_listBase.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_scene_types.h" + +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_depsgraph.h" +#include "BKE_ipo.h" +#include "BKE_modifier.h" +#include "BKE_object.h" + +#include "BKE_global.h" +#include "BKE_utildefines.h" + +//#include "BIF_keyframing.h" +#include "BSE_editipo.h" + +#include "BIF_poselib.h" +#include "BIF_interface.h" +#include "BIF_editaction.h" +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" + +#include "blendef.h" + +#include "PIL_time.h" /* sleep */ +#include "mydevice.h" + +/* ************************************************************* */ +/* == POSE-LIBRARY TOOL FOR BLENDER == + * + * Overview: + * This tool allows animators to store a set of frequently used poses to dump into + * the active action to help in "budget" productions to quickly block out new actions. + * It acts as a kind of "glorified clipboard for poses", allowing for naming of poses. + * + * Features: + * - PoseLibs are simply normal Actions, but with a poselib + * - Each "pose" is simply a set of keyframes that occur on a particular frame + * -> a bPoseLibRef struct is used to identify and label poses in the Action + * -> all bPoseLibRefs are stored in the order they were added + * -> keys for poses should occur on each positively numbered frame (starting from frame 1) + * - The Scrollwheel or PageUp/Down buttons when used in a special mode or after pressing/holding + * [a modifier] key, cycles through the poses available for the active pose's poselib, allowing the + * animator to preview what action best suits that pose + */ +/* ************************************************************* */ + +/* gets list of poses in poselib as a string */ +char *poselib_build_poses_menu (bPoseLib *pl, char title[]) +{ + DynStr *pupds= BLI_dynstr_new(); + bPoseLibRef *plr; + char *str; + char buf[64]; + int i; + + /* add title first */ + sprintf(buf, "%s%%t|", title); + BLI_dynstr_append(pupds, buf); + + /* loop through keyingsets, adding them */ + for (plr=pl->poses.first, i=1; plr; plr=plr->next, i++) { + BLI_dynstr_append(pupds, plr->name); + + sprintf(buf, "%%x%d", i); + BLI_dynstr_append(pupds, buf); + + if (plr->next) + BLI_dynstr_append(pupds, "|"); + } + + /* convert to normal MEM_malloc'd string */ + str= BLI_dynstr_get_cstring(pupds); + BLI_dynstr_free(pupds); + + return str; +} + +/* finds an unique name for pose to be added to poselib */ +void poselib_unique_pose_name (bPoseLib *pl, char name[]) +{ + bPoseLibRef *plr; + char tempname[32]; + int number = 1, exists = 0; + char *dot; + + /* See if we are given an empty string */ + if (name[0] == '\0') { + /* give it default name first */ + strcpy(name, "Pose"); + } + + /* See if we even need to do this */ + for (plr= pl->poses.first; plr; plr= plr->next) { + if (!strcmp(name, plr->name)) { + exists = 1; + break; + } + } + + if (exists == 0) + return; + + /* Strip off the suffix */ + dot = strchr(name, '.'); + if (dot) + *dot=0; + + for (number = 1; number <= 999; number++) { + sprintf(tempname, "%s.%03d", name, number); + + exists = 0; + for (plr= pl->poses.first; plr; plr= plr->next) { + if (strcmp(name, tempname)==0) { + exists = 1; + break; + } + } + if (exists == 0) { + BLI_strncpy(name, tempname, 32); + return; + } + } +} + +/* gets the first available frame in poselib to store a pose on + * - frames start from 1, and a pose should occur on every frame... 0 is error! + */ +int poselib_get_free_index (bPoseLib *pl) +{ + bPoseLibRef *plr; + int low=0, high=0; + + /* sanity checks */ + if (ELEM(NULL, pl, pl->poses.first)) return 1; + + /* loop over poses finding various values (poses are not stored in chronological order) */ + for (plr= pl->poses.first; plr; plr= plr->next) { + /* only increase low if value is 1 greater than low, to find "gaps" where + * poses were removed from the poselib + */ + if (plr->frame == (low + 1)) + low++; + + /* value replaces high if it is the highest value encountered yet */ + if (plr->frame > high) + high= plr->frame; + } + + /* - if low is not equal to high, then low+1 is a gap + * - if low is equal to high, then high+1 is the next index (add at end) + */ + if (low < high) + return (low + 1); + else + return (high + 1); +} + +/* ************************************************************* */ + +/* Initialise a new poselib */ +bPoseLib *poselib_init_new (Object *ob) +{ + bPose *pose= (ob) ? ob->pose : NULL; + bAction *act; + bPoseLib *pl; + + if (ELEM(NULL, ob, pose)) + return NULL; + + /* init pose's poselib action */ + if (pose->poselib == NULL) + pose->poselib= add_empty_action("PoseLib"); + act= pose->poselib; + + /* init actions's poselib data */ + if (act->poselib == NULL) + act->poselib= MEM_callocN(sizeof(bPoseLib), "bPoseLib"); + pl= act->poselib; + + return pl; +} + + +/* This function adds an ipo-curve of the right type where it's needed */ +static IpoCurve *poselib_verify_icu (Ipo *ipo, int adrcode) +{ + IpoCurve *icu; + + for (icu= ipo->curve.first; icu; icu= icu->next) { + if (icu->adrcode==adrcode) break; + } + if (icu==NULL) { + icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); + + icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ; + if (ipo->curve.first==NULL) icu->flag |= IPO_ACTIVE; /* first one added active */ + + icu->blocktype= ID_PO; + icu->adrcode= adrcode; + + set_icu_vars(icu); + + BLI_addtail(&ipo->curve, icu); + } + + return icu; +} + +/* This tool adds the current pose to the poselib + * Note: Standard insertkey cannot be used for this due to its limitations + */ +void poselib_add_current_pose (Object *ob, int val) +{ + bArmature *arm= (ob) ? ob->data : NULL; + bPose *pose= (ob) ? ob->pose : NULL; + bPoseChannel *pchan; + bPoseLib *pl; + bPoseLibRef *plr; + bAction *act; + bActionChannel *achan; + IpoCurve *icu; + int frame; + char name[32]; + + /* sanity check */ + if (ELEM3(NULL, ob, arm, pose)) + return; + + /* mode - add new or replace existing */ + if (val == 0) { + if (pose->poselib && pose->poselib->poselib->poses.first) { + val= pupmenu("PoseLib Add Current Pose%t|Add New%x1|Replace Existing%x2"); + if (val <= 0) return; + } + else + val= 1; + } + + if ((pose->poselib) && (val == 2)) { + char *menustr; + + /* get poselib */ + act= pose->poselib; + pl= act->poselib; + + /* get the pose to replace */ + menustr= poselib_build_poses_menu(pl, "Replace PoseLib Pose"); + val= pupmenu(menustr); + if (menustr) MEM_freeN(menustr); + + if (val <= 0) return; + plr= BLI_findlink(&pl->poses, val-1); + if (plr == NULL) return; + + /* get the frame from the poselib */ + frame= plr->frame; + } + else { + /* get name of pose */ + sprintf(name, "Pose"); + if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) + return; + + /* get/initialise poselib */ + pl= poselib_init_new(ob); + act= pose->poselib; + + /* validate name and get frame */ + poselib_unique_pose_name(pl, name); + frame= poselib_get_free_index(pl); + + /* add pose to poselib */ + plr= MEM_callocN(sizeof(bPoseLibRef), "bPoseLibRef"); + BLI_strncpy(plr->name, name, sizeof(plr->name)); + plr->frame= frame; + BLI_addtail(&pl->poses, plr); + } + + /* loop through selected posechannels, keying their pose to the action */ + for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { + /* check if available */ + if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { + if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) { + /* make action-channel if needed */ + achan= verify_action_channel(act, pchan->name); + + /* make ipo if needed... */ + if (achan->ipo == NULL) + achan->ipo= add_ipo(achan->name, ID_PO); + + /* add missing ipo-curves and insert keys */ + #define INSERT_KEY_ICU(adrcode, data) {\ + icu= poselib_verify_icu(achan->ipo, adrcode); \ + insert_vert_icu(icu, frame, data, 1); \ + } + + INSERT_KEY_ICU(AC_LOC_X, pchan->loc[0]) + INSERT_KEY_ICU(AC_LOC_Y, pchan->loc[1]) + INSERT_KEY_ICU(AC_LOC_Z, pchan->loc[2]) + INSERT_KEY_ICU(AC_SIZE_X, pchan->size[0]) + INSERT_KEY_ICU(AC_SIZE_Y, pchan->size[1]) + INSERT_KEY_ICU(AC_SIZE_Z, pchan->size[2]) + INSERT_KEY_ICU(AC_QUAT_W, pchan->quat[0]) + INSERT_KEY_ICU(AC_QUAT_X, pchan->quat[1]) + INSERT_KEY_ICU(AC_QUAT_Y, pchan->quat[2]) + INSERT_KEY_ICU(AC_QUAT_Z, pchan->quat[3]) + } + } + } + + /* store new 'active' pose number */ + pl->active_nr= BLI_countlist(&pl->poses); + + BIF_undo_push("PoseLib Add Pose"); + allqueue(REDRAWBUTSEDIT, 0); +} + + +/* This tool removes the pose that the user selected from the poselib (or the provided pose) */ +void poselib_remove_pose (Object *ob, bPoseLibRef *plr) +{ + bPose *pose= (ob) ? ob->pose : NULL; + bAction *act= (pose) ? pose->poselib : NULL; + bActionChannel *achan; + bPoseLib *pl= (act) ? act->poselib : NULL; + char *menustr; + int val; + + /* check if valid poselib */ + if (ELEM(NULL, ob, pose)) { + error("PoseLib is only for Armatures in PoseMode"); + return; + } + if (ELEM(NULL, act, pl)) { + error("Pose doesn't have a valid PoseLib"); + return; + } + + /* get index (and pointer) of pose to remove */ + if (plr == NULL) { + menustr= poselib_build_poses_menu(pl, "Remove PoseLib Pose"); + val= pupmenu(menustr); + if (menustr) MEM_freeN(menustr); + + if (val <= 0) return; + plr= BLI_findlink(&pl->poses, val-1); + if (plr == NULL) return; + } + else { + // TODO: we should really check if pose occurs in this poselib + } + + /* remove relevant keyframes */ + for (achan= act->chanbase.first; achan; achan= achan->next) { + Ipo *ipo= achan->ipo; + IpoCurve *icu; + BezTriple *bezt; + int i; + + for (icu= ipo->curve.first; icu; icu= icu->next) { + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + /* check if remove... */ + if (IS_EQ(bezt->vec[1][0], plr->frame)) { + delete_icu_key(icu, i); + break; + } + } + } + } + + /* remove poselib from list */ + BLI_freelinkN(&pl->poses, plr); + + /* fix active pose number */ + pl->active_nr= 0; + + /* undo + redraw */ + BIF_undo_push("PoseLib Remove Pose"); + allqueue(REDRAWBUTSEDIT, 0); +} + + +/* This tool renames the pose that the user selected from the poselib */ +void poselib_rename_pose (Object *ob) +{ + bPose *pose= (ob) ? ob->pose : NULL; + bAction *act= (pose) ? pose->poselib : NULL; + bPoseLib *pl= (act) ? act->poselib : NULL; + bPoseLibRef *plr; + char *menustr, name[32]; + int val; + + /* check if valid poselib */ + if (ELEM(NULL, ob, pose)) { + error("PoseLib is only for Armatures in PoseMode"); + return; + } + if (ELEM(NULL, act, pl)) { + error("Pose doesn't have a valid PoseLib"); + return; + } + + /* get index of pose to remove */ + menustr= poselib_build_poses_menu(pl, "Rename PoseLib Pose"); + val= pupmenu(menustr); + if (menustr) MEM_freeN(menustr); + + if (val <= 0) return; + plr= BLI_findlink(&pl->poses, val-1); + if (plr == NULL) return; + + /* get name of pose */ + sprintf(name, plr->name); + if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) + return; + + /* validate name */ + poselib_unique_pose_name(pl, name); // hmm what happens with the old pose's name... + + /* copy name */ + BLI_strncpy(plr->name, name, sizeof(plr->name)); + + /* undo and update */ + BIF_undo_push("PoseLib Rename Pose"); + allqueue(REDRAWBUTSEDIT, 0); +} + + +/* ************************************************************* */ + +/* simple struct for storing backup info */ +typedef struct tPoseLib_Backup { + struct tPoseLib_Backup *next, *prev; + + float oldloc[3]; + float oldsize[3]; + float oldquat[4]; + + float *loc, *size, *quat; +} tPoseLib_Backup; + +/* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ +static void poselib_backup_posecopy (ListBase *backups, bPose *pose) +{ + bAction *poselib= pose->poselib; + bActionChannel *achan; + bPoseChannel *pchan; + + /* for each posechannel that has an actionchannel in */ + for (achan= poselib->chanbase.first; achan; achan= achan->next) { + /* try to find posechannel */ + pchan= get_pose_channel(pose, achan->name); + + /* backup data if available */ + if (pchan) { + tPoseLib_Backup *plb; + + plb= MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup"); + + VECCOPY(plb->oldloc, pchan->loc); + VECCOPY(plb->oldsize, pchan->size); + QUATCOPY(plb->oldquat, pchan->quat); + + plb->loc= pchan->loc; + plb->size= pchan->size; + plb->quat= pchan->quat; + + BLI_addtail(backups, plb); + } + } +} + +/* Restores original pose - doesn't do constraints currently */ +static void poselib_backup_restore (ListBase *backups) +{ + tPoseLib_Backup *plb; + + for (plb= backups->first; plb; plb= plb->next) { + VECCOPY(plb->loc, plb->oldloc); + VECCOPY(plb->size, plb->oldsize); + VECCOPY(plb->quat, plb->oldquat); + } +} + +/* ---------------------------- */ + +/* Applies the appropriate stored pose from the pose-library to the current pose + * - assumes that a valid object, with a poselib has been supplied + * - gets the string to print in the header + * - this code is based on the code for extract_pose_from_action in blenkernel/action.c + */ +static void poselib_apply_pose (Object *ob, bPoseLibRef *plr, char headerstr[]) +{ + bPose *pose= ob->pose; + bPoseChannel *pchan; + bAction *act= pose->poselib; + bActionChannel *achan; + IpoCurve *icu; + int frame= plr->frame; + + /* start applying - only those channels which have a key at this point in time! */ + for (achan= act->chanbase.first; achan; achan= achan->next) { + short found= 0; + + /* apply this achan? */ + if (achan->ipo) { + /* find a keyframe at this frame */ + for (icu= achan->ipo->curve.first; icu; icu= icu->next) { + BezTriple *bezt; + int i; + + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + if (IN_RANGE(bezt->vec[1][0], (frame-0.5f), (frame+0.5f))) { + found= 1; + break; + } + } + + if (found) break; + } + + /* apply pose */ + if (found) { + pchan= get_pose_channel(pose, achan->name); + + if (pchan) { + /* Evaluates and sets the internal ipo values */ + calc_ipo(achan->ipo, frame); + /* This call also sets the pchan flags */ + execute_action_ipo(achan, pchan); + } + } + } + + /* tag achan as having been used or not... */ + if (found) + achan->flag |= ACHAN_SELECTED; + else + achan->flag &= ~ACHAN_SELECTED; + } +} + +/* Auto-keys/tags bones affected by the pose used from the poselib */ +static void poselib_keytag_pose (Object *ob) +{ + bPose *pose= ob->pose; + bPoseChannel *pchan; + bAction *act= pose->poselib; + bActionChannel *achan; + + /* start tagging/keying */ + for (achan= act->chanbase.first; achan; achan= achan->next) { + /* only for selected action channels */ + if (achan->flag & ACHAN_SELECTED) { + pchan= get_pose_channel(ob->pose, achan->name); + + if (pchan) { + if (G.flags & G_RECORDKEYS) { + ID *id= &ob->id; + + /* Set keys on pose */ + if (pchan->flag & POSE_ROT) { + insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0); + } + if (pchan->flag & POSE_SIZE) { + insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0); + } + if (pchan->flag & POSE_LOC) { + insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0); + insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0); + } + + /* clear any unkeyed tags */ + if (pchan->bone) + pchan->bone->flag &= ~BONE_UNKEYED; + } + else { + /* add unkeyed tags */ + if (pchan->bone) + pchan->bone->flag |= BONE_UNKEYED; + } + } + } + } +} + +/* ---------------------------- */ + +/* defines for psoelib_preview_poses --> ret_val values */ +enum { + PL_PREVIEW_RUNNING = 0, + PL_PREVIEW_CONFIRM, + PL_PREVIEW_CANCEL +}; + +/* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown */ +void poselib_preview_poses (Object *ob) +{ + ListBase backups = {NULL, NULL}; + + bPose *pose= (ob) ? (ob->pose) : NULL; + bArmature *arm= (ob) ? (ob->data) : NULL; + bAction *act= (pose) ? (pose->poselib) : NULL; + bPoseLib *pl= (act) ? (act->poselib) : NULL; + bPoseLibRef *plr= (pl->active_nr) ? BLI_findlink(&pl->poses, pl->active_nr-1) : pl->poses.first; + + short ret_val=PL_PREVIEW_RUNNING, val=0, redraw=1, firsttime=1; + unsigned short event; + char headerstr[200]; + + /* check if valid poselib */ + if (ELEM(NULL, ob, pose)) { + error("PoseLib is only for Armatures in PoseMode"); + return; + } + if (ELEM(NULL, act, pl)) { + error("Pose doesn't have a valid PoseLib"); + return; + } + if (plr == NULL) { + error("PoseLib has no poses to preview"); + return; + } + + /* make backup of current pose for restoring pose */ + poselib_backup_posecopy(&backups, pose); + + /* set depsgraph flags */ + /* make sure the lock is set OK, unlock can be accidentally saved? */ + pose->flag |= POSE_LOCKED; + pose->flag &= ~POSE_DO_UNLOCK; + + + /* start preview loop */ + while (ret_val == PL_PREVIEW_RUNNING) { + /* preview a pose */ + if (redraw) { + /* don't clear pose if firsttime */ + if (firsttime == 0) + poselib_backup_restore(&backups); + else + firsttime = 0; + + /* pose should be the right one to draw */ + poselib_apply_pose(ob, plr, headerstr); + + /* old optimize trick... this enforces to bypass the depgraph + * - note: code copied from transform_generics.c -> recalcData() + */ + if ((arm->flag & ARM_DELAYDEFORM)==0) { + Base *base; + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + + /* bah, softbody exception... recalcdata doesnt reset */ + for (base= FIRSTBASE; base; base= base->next) { + if (base->object->recalc & OB_RECALC_DATA) + if (modifiers_isSoftbodyEnabled(base->object)) { + base->object->softflag |= OB_SB_REDO; + } + } + } + else + where_is_pose(ob); + + /* do header print */ + sprintf(headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", plr->name); + headerprint(headerstr); + + /* redraw... */ + force_draw(0); + redraw= 0; + } + + /* essential for idling subloop */ + if( qtest()==0) PIL_sleep_ms(2); + + /* emptying queue and reading events */ + while ( qtest() ) { + event= extern_qread(&val); + + /* event processing */ + if (val) { + /* exit */ + if (ELEM(event, ESCKEY, RIGHTMOUSE)) + ret_val= PL_PREVIEW_CANCEL; + else if (ELEM3(event, LEFTMOUSE, RETKEY, SPACEKEY)) + ret_val= PL_PREVIEW_CONFIRM; + + /* change pose */ + else if (ELEM(event, PAGEUPKEY, WHEELUPMOUSE)) { + /* find previous pose - go back to end of list if no previous (cyclic) */ + plr= (plr->prev) ? plr->prev : pl->poses.last; + redraw= 1; + } + else if (ELEM(event, PAGEDOWNKEY, WHEELDOWNMOUSE)) { + /* find next pose - go back to start of list if no next (cyclic) */ + plr= (plr->next) ? plr->next : pl->poses.first; + redraw= 1; + } + } + } + } + + /* clear pose if cancelled */ + if (ret_val == PL_PREVIEW_CANCEL) { + poselib_backup_restore(&backups); + where_is_pose(ob); + } + BLI_freelistN(&backups); + + /* auto-keying if not cancelled */ + if (ret_val == PL_PREVIEW_CONFIRM) + poselib_keytag_pose(ob); + + /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */ + pose->flag |= POSE_DO_UNLOCK; + + /* Update event for pose and deformation children */ + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + + /* updates */ + if (G.flags & G_RECORDKEYS) { + remake_action_ipos(ob->action); + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + else { + /* need to trick depgraph, action is not allowed to execute on pose */ + where_is_pose(ob); + ob->recalc= 0; + + allqueue(REDRAWVIEW3D, 0); + } + + BIF_undo_push("PoseLib Apply Pose"); +} diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 72107ec7003..5415f03701e 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -125,6 +125,7 @@ #include "BIF_meshtools.h" #include "BIF_mywindow.h" #include "BIF_oops.h" +#include "BIF_poselib.h" #include "BIF_poseobject.h" #include "BIF_outliner.h" #include "BIF_resources.h" @@ -2132,7 +2133,16 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) selectconnected_nurb(); } else if(ob && (ob->flag & OB_POSEMODE)) { - selectconnected_posearmature(); + if (G.qual == LR_CTRLKEY) + poselib_preview_poses(ob); + else if (G.qual == LR_SHIFTKEY) + poselib_add_current_pose(ob, 0); + else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) + poselib_rename_pose(ob); + else if (G.qual == LR_ALTKEY) + poselib_remove_pose(ob, NULL); + else + selectconnected_posearmature(); } else { if(FACESEL_PAINT_TEST) { From debf29022a1a720cc1ea324ca3d345f8663a84fc Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 26 Dec 2007 15:25:30 +0000 Subject: [PATCH 52/99] =Particle bugfix= Hair keys were saved via a non-sdna function, which resulted in endian problems. As ton pointed out on irc, he invented sdna for a reason! --- source/blender/blenloader/intern/writefile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 90f48868911..f1fe64eb820 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -556,7 +556,7 @@ static void write_particlesystems(WriteData *wd, ListBase *particles) ParticleData *pa = psys->particles; for(a=0; atotpart; a++, pa++) - writedata(wd, DATA, MEM_allocN_len(pa->hair),pa->hair); + writestruct(wd, DATA, "HairKey", pa->totkey, pa->hair); } } if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child); From 237ba0291a31ce50f2a888cad03169022a39ad87 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Wed, 26 Dec 2007 16:07:16 +0000 Subject: [PATCH 53/99] == Sequencer == Moved N-keys dialog into panel (sub panel of "Scene") _much_ better :) Since UI-code isn't directly my main field of coding, please check thoroughly... --- source/blender/include/BIF_butspace.h | 3 +- source/blender/include/BIF_editseq.h | 2 - source/blender/include/butspace.h | 11 +- source/blender/src/butspace.c | 5 + source/blender/src/buttons_scene.c | 505 ++++++++++++++++++++++- source/blender/src/drawseq.c | 529 ------------------------- source/blender/src/editseq.c | 1 + source/blender/src/header_buttonswin.c | 9 + source/blender/src/header_seq.c | 5 +- source/blender/src/space.c | 18 +- 10 files changed, 540 insertions(+), 548 deletions(-) diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h index df60a0c9a08..9d5e1961178 100644 --- a/source/blender/include/BIF_butspace.h +++ b/source/blender/include/BIF_butspace.h @@ -86,9 +86,10 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev); #define TAB_OBJECT_PARTICLE 2 #define TAB_SCENE_RENDER 0 -#define TAB_SCENE_WORLD 1 +#define TAB_SCENE_WORLD 1 #define TAB_SCENE_ANIM 2 #define TAB_SCENE_SOUND 3 +#define TAB_SCENE_SEQUENCER 4 /* buts->scaflag */ diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h index 13cb059d885..92046f74009 100644 --- a/source/blender/include/BIF_editseq.h +++ b/source/blender/include/BIF_editseq.h @@ -128,8 +128,6 @@ start and end are from the start and fixed length of the sequence. (seq)->endstill = 0; \ } */ -/* drawseq.c */ -void do_seqbuttons(short); #endif diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 7b6213be38f..7eabc367782 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -64,6 +64,8 @@ extern void do_render_panels(unsigned short event); extern void anim_panels(void); extern void sound_panels(void); extern void do_soundbuts(unsigned short event); +extern void sequencer_panels(void); +extern void do_sequencer_panels(unsigned short event); /* object */ extern void object_panels(void); @@ -298,7 +300,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_AO_FALLOFF 1506 /* *********************** */ -#define B_RENDERBUTS 1700 +#define B_RENDERBUTS 1690 +#define B_SEQUENCERBUTS 1699 #define B_FS_PIC 1601 #define B_FS_BACKBUF 1602 @@ -347,6 +350,12 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_ADD_RENDERLAYER 1645 #define B_SET_PASS 1646 +#define B_SEQ_BUT_PLUGIN 1691 +#define B_SEQ_BUT_RELOAD 1692 +#define B_SEQ_BUT_EFFECT 1693 +#define B_SEQ_BUT_RELOAD_ALL 1694 +#define B_SEQ_BUT_TRANSFORM 1695 + /* *********************** */ #define B_ARMATUREBUTS 1800 #define B_POSE 1701 diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c index 2eddd362b62..e8062422e2a 100644 --- a/source/blender/src/butspace.c +++ b/source/blender/src/butspace.c @@ -572,6 +572,9 @@ void do_butspace(unsigned short event) else if(event<=B_RENDERBUTS) { do_render_panels(event); // buttons_scene.c } + else if(event<=B_SEQUENCERBUTS) { + do_sequencer_panels(event); + } else if(event<=B_COMMONEDITBUTS) { do_common_editbuts(event); } @@ -725,6 +728,8 @@ void drawbutspace(ScrArea *sa, void *spacedata) if(tab== TAB_SCENE_RENDER) render_panels(); + else if(tab == TAB_SCENE_SEQUENCER) + sequencer_panels(); else if(tab == TAB_SCENE_ANIM) anim_panels(); else if(tab == TAB_SCENE_SOUND) diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 8fd74ddc08e..b6b8805ba5c 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -41,6 +41,7 @@ #include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_sound_types.h" +#include "DNA_sequence_types.h" #include "DNA_userdef_types.h" #include "DNA_packedFile_types.h" @@ -71,6 +72,7 @@ #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_toolbox.h" +#include "BIF_editseq.h" #include "BIF_butspace.h" @@ -84,6 +86,7 @@ #include "BKE_writeavi.h" #include "BKE_writeffmpeg.h" #include "BKE_image.h" +#include "BKE_plugin_types.h" #include "BLI_threads.h" @@ -91,8 +94,11 @@ #include "BIF_writeimage.h" #include "BIF_writeavicodec.h" -#include "BSE_seqaudio.h" #include "BSE_headerbuttons.h" +#include "BSE_sequence.h" +#include "BSE_seqeffects.h" +#include "BSE_seqscopes.h" +#include "BSE_seqaudio.h" #include "RE_pipeline.h" @@ -466,6 +472,503 @@ static void sound_panel_sound(bSound *sound) } } +/* ************************* Sequencer *********************** */ + +#define SEQ_PANEL_EDITING 1 +#define SEQ_PANEL_INPUT 2 +#define SEQ_PANEL_FILTER 4 +#define SEQ_PANEL_EFFECT 8 +#define SEQ_PANEL_PROXY 16 + +static char* seq_panel_blend_modes() +{ + static char string[2048]; + char formatstring[2048]; + + strcpy(formatstring, "Blend mode: %%t|%s %%x%d|%s %%x%d"); + sprintf(string, formatstring, + "REPLACE", SEQ_BLEND_REPLACE, + "TODO: ALPHA OVER", SEQ_BLEND_ALPHA_OVER); + return string; + +} + +static void seq_panel_editing() +{ + Sequence *last_seq = get_last_seq(); + char * seq_names[] = { "Image", "Meta", "Scene", "Movie", + "Snd RAM", "Snd HD", + "", "Effect" }; + uiBlock *block; + + block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing", + UI_EMBOSS, UI_HELV, curarea->win); + + if(uiNewPanel(curarea, block, "Edit", "Sequencer", + 10, 230, 318, 204) == 0) return; + + uiDefBut(block, LABEL, + 0, (last_seq->type >= SEQ_EFFECT) ? + "Effect" : seq_names[last_seq->type], + 10,140,60,19, 0, + 0, 0, 0, 0, ""); + + uiDefBut(block, TEX, + B_NOP, "Name: ", + 70,140,180,19, last_seq->name+2, + 0.0, 21.0, 100, 0, ""); + + uiDefButI(block, MENU, B_SEQ_BUT_RELOAD, seq_panel_blend_modes(), + 10, 120, 120, 19, &last_seq->blend_mode, + 0,0,0,0, "Strip Blend Mode"); + + if (last_seq->blend_mode > 0) { + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Blend:", + 130, 120, 120, 19, &last_seq->blend_opacity, + 0.0, 100.0, 100.0, 0, + "Blend opacity"); + } + + uiDefButBitI(block, TOG, SEQ_MUTE, + B_SEQ_BUT_RELOAD_ALL, "Mute", + 10,100,60,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Mute the current strip."); + + uiDefButBitI(block, TOG, SEQ_LOCK, + B_NOP, "Lock", + 70,100,60,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Lock strip, so that it can't be transformed."); + + uiDefButBitI(block, TOG, SEQ_IPO_FRAME_LOCKED, + B_SEQ_BUT_RELOAD_ALL, "IPO Frame locked", + 130,100,120,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Lock the IPO coordinates to the " + "global frame counter."); + + if (!(last_seq->flag & SEQ_LOCK)) { + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "Start", + 10, 80, 120, 20, &last_seq->start, + 0.0, MAXFRAMEF, 0.0, 0.0, "Start of strip"); + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "Chan", + 130, 80, 120, 20, &last_seq->machine, + 0.0, MAXSEQ, 0.0, 0.0, "Channel used (Y position)"); + + if (last_seq->type == SEQ_IMAGE) { + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "Start-Still", + 10, 60, 120, 20, &last_seq->startstill, + 0.0, MAXFRAMEF, 0.0, 0.0, "Start still"); + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "End-Still", + 130, 60, 120, 19, &last_seq->endstill, + 0.0, MAXFRAMEF, 0.0, 0.0, "End still"); + } else { + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "Start-Ofs", + 10, 60, 120, 20, &last_seq->startofs, + 0.0, last_seq->len, 0.0, 0.0, "Start offset"); + uiDefButI(block, NUM, + B_SEQ_BUT_TRANSFORM, "End-Ofs", + 130, 60, 120, 19, &last_seq->endofs, + 0.0, last_seq->len, 0.0, 0.0, "End offset"); + } + } +} + +static void seq_panel_input() +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_input", + UI_EMBOSS, UI_HELV, curarea->win); + + if(uiNewPanel(curarea, block, "Input", "Sequencer", + 10, 230, 318, 204) == 0) return; + + + uiDefButBitI(block, TOG, SEQ_USE_CROP, + B_SEQ_BUT_RELOAD, "Use Crop", + 10,100,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Crop image before processing."); + + if (last_seq->flag & SEQ_USE_CROP) { + if (!last_seq->strip->crop) { + last_seq->strip->crop = + MEM_callocN(sizeof(struct StripCrop), + "StripCrop"); + } + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Top", + 10, 80, 120, 20, &last_seq->strip->crop->top, + 0.0, 4096, 0.0, 0.0, "Top of source image"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Bottom", + 130, 80, 120, 20, &last_seq->strip->crop->bottom, + 0.0, 4096, 0.0, 0.0, "Bottom of source image"); + + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Left", + 10, 60, 120, 20, &last_seq->strip->crop->left, + 0.0, 4096, 0.0, 0.0, "Left"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Right", + 130, 60, 120, 19, &last_seq->strip->crop->right, + 0.0, 4096, 0.0, 0.0, "Right"); + } + + uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, + B_SEQ_BUT_RELOAD, "Use Translate", + 10,40,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Translate image before processing."); + + if (last_seq->flag & SEQ_USE_TRANSFORM) { + if (!last_seq->strip->transform) { + last_seq->strip->transform = + MEM_callocN(sizeof(struct StripTransform), + "StripTransform"); + } + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "X-Ofs", + 10, 20, 120, 20, &last_seq->strip->transform->xofs, + 0.0, 4096, 0.0, 0.0, "X Offset"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Y-Ofs", + 130, 20, 120, 20, &last_seq->strip->transform->yofs, + 0.0, 4096, 0.0, 0.0, "Y Offset"); + } + + + uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "Preseek:", + 10,0,150,19, &last_seq->anim_preseek, + 0.0, 50.0, 100,0,"On MPEG-seeking preseek this many frames"); + +} + +static void seq_panel_filter_video() +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter", + UI_EMBOSS, UI_HELV, curarea->win); + + if(uiNewPanel(curarea, block, "Filter", "Sequencer", + 10, 230, 318, 204) == 0) return; + + + uiBlockBeginAlign(block); + + + uiDefButBitI(block, TOG, SEQ_MAKE_PREMUL, + B_SEQ_BUT_RELOAD, "Convert to Premul", + 10,110,150,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Converts RGB values to become premultiplied with Alpha"); + + uiDefButBitI(block, TOG, SEQ_FILTERY, + B_SEQ_BUT_RELOAD, "FilterY", + 10,90,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "For video movies to remove fields"); + + uiDefButBitI(block, TOG, SEQ_MAKE_FLOAT, + B_SEQ_BUT_RELOAD, "Make Float", + 85,90,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Convert input to float data"); + + uiDefButBitI(block, TOG, SEQ_FLIPX, + B_SEQ_BUT_RELOAD, "FlipX", + 10,70,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Flip on the X axis"); + uiDefButBitI(block, TOG, SEQ_FLIPY, + B_SEQ_BUT_RELOAD, "FlipY", + 85,70,75,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Flip on the Y axis"); + + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Mul:", + 10,50,150,19, &last_seq->mul, + 0.001, 5.0, 100, 0, + "Multiply colors"); + + uiDefButBitI(block, TOG, SEQ_REVERSE_FRAMES, + B_SEQ_BUT_RELOAD, "Reverse Frames", + 10,30,150,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Reverse frame order"); + + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Strobe:", + 10,10,150,19, &last_seq->strobe, + 1.0, 30.0, 100, 0, + "Only display every nth frame"); + + uiBlockEndAlign(block); + +} + + +static void seq_panel_filter_audio() +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter", + UI_EMBOSS, UI_HELV, curarea->win); + + if(uiNewPanel(curarea, block, "Filter", "Sequencer", + 10, 230, 318, 204) == 0) return; + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, ""); + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Pan:", 10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, ""); + uiBlockEndAlign(block); +} + +static void seq_panel_effect() +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_effect", + UI_EMBOSS, UI_HELV, curarea->win); + + if(uiNewPanel(curarea, block, "Effect", "Sequencer", + 10, 230, 318, 204) == 0) return; + + if(last_seq->type == SEQ_PLUGIN) { + PluginSeq *pis; + VarStruct *varstr; + int a, xco, yco; + + get_sequence_effect(last_seq);/* make sure, plugin is loaded */ + + pis= last_seq->plugin; + if(pis->vars==0) return; + + varstr= pis->varstr; + if(varstr) { + for(a=0; avars; a++, varstr++) { + xco= 150*(a/6)+10; + yco= 125 - 20*(a % 6)+1; + uiDefBut(block, varstr->type, B_SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip); + + } + } + return; + } + + uiBlockBeginAlign(block); + + if(last_seq->type==SEQ_WIPE){ + WipeVars *wipe = (WipeVars *)last_seq->effectdata; + char formatstring[256]; + + strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255); + uiDefButS(block, MENU,B_SEQ_BUT_EFFECT, formatstring, 10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed"); + uiDefButF(block, NUM,B_SEQ_BUT_EFFECT,"Blur:", 10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge"); + switch(wipe->wipetype){ /*Skip Types that do not require angle*/ + case DO_IRIS_WIPE: + case DO_CLOCK_WIPE: + break; + + default: + uiDefButF(block, NUM,B_SEQ_BUT_EFFECT,"Angle:", 10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge"); + } + uiDefButS(block, TOG,B_SEQ_BUT_EFFECT,"Wipe In", 10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe"); + } else if(last_seq->type==SEQ_GLOW){ + GlowVars *glow = (GlowVars *)last_seq->effectdata; + + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Threshold:", 10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Clamp:", 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Boost factor:", 10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Blur distance:", 10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect"); + uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect"); + uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only"); + } + else if(last_seq->type==SEQ_TRANSFORM){ + TransformVars *transform = (TransformVars *)last_seq->effectdata; + + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "xScale Start:", 10,70,150,19, &transform->ScalexIni, 0.0, 10.0, 0, 0, "X Scale Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "xScale End:", 160,70,150,19, &transform->ScalexFin, 0.0, 10.0, 0, 0, "X Scale End"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "yScale Start:", 10,50,150,19, &transform->ScaleyIni, 0.0, 10.0, 0, 0, "Y Scale Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "yScale End:", 160,50,150,19, &transform->ScaleyFin, 0.0, 10.0, 0, 0, "Y Scale End"); + + uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Percent", 10, 30, 150, 19, &transform->percent, 0.0, 1.0, 0.0, 0.0, "Percent Translate"); + uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Pixels", 160, 30, 150, 19, &transform->percent, 0.0, 0.0, 0.0, 0.0, "Pixels Translate"); + if(transform->percent==1){ + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -500.0, 500.0, 0, 0, "X Position Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -500.0, 500.0, 0, 0, "X Position End"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -500.0, 500.0, 0, 0, "Y Position Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -500.0, 500.0, 0, 0, "Y Position End"); + } else { + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -10000.0, 10000.0, 0, 0, "X Position Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -10000.0, 10000.0, 0, 0, "X Position End"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -10000.0, 10000.0, 0, 0, "Y Position Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -10000.0, 10000.0, 0, 0, "Y Position End"); + + } + + + + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "rot Start:",10,-30,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start"); + uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "rot End:",160,-30,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End"); + + uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "No Interpolat", 10, -50, 100, 19, &transform->interpolation, 0.0, 0.0, 0.0, 0.0, "No interpolation"); + uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Bilinear", 101, -50, 100, 19, &transform->interpolation, 0.0, 1.0, 0.0, 0.0, "Bilinear interpolation"); + uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Bicubic", 202, -50, 100, 19, &transform->interpolation, 0.0, 2.0, 0.0, 0.0, "Bicubic interpolation"); + } else if(last_seq->type==SEQ_COLOR) { + SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata; + uiDefButF(block, COL, B_SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, ""); + } else if(last_seq->type==SEQ_SPEED){ + SpeedControlVars *sp = + (SpeedControlVars *)last_seq->effectdata; + + uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed"); + + uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE, + B_SEQ_BUT_RELOAD, + "IPO is velocity", + 10,50,150,19, &sp->flags, + 0.0, 1.0, 0, 0, + "Interpret the IPO value as a " + "velocity instead of a frame number"); + + uiDefButBitI(block, TOG, SEQ_SPEED_BLEND, + B_SEQ_BUT_RELOAD, + "Enable frame blending", + 10,30,150,19, &sp->flags, + 0.0, 1.0, 0, 0, + "Blend two frames into the " + "target for a smoother result"); + + uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y, + B_SEQ_BUT_RELOAD, + "IPO value runs from [0..1]", + 10,10,150,19, &sp->flags, + 0.0, 1.0, 0, 0, + "Scale IPO value to get the " + "target frame number."); + } + + uiBlockEndAlign(block); +} + +static void seq_panel_proxy() +{ + Sequence *last_seq = get_last_seq(); + uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_proxy", + UI_EMBOSS, UI_HELV, curarea->win); + + if(uiNewPanel(curarea, block, "Proxy", "Sequencer", + 10, 230, 318, 204) == 0) return; + + uiBlockBeginAlign(block); + + uiDefButBitI(block, TOG, SEQ_USE_PROXY, + B_SEQ_BUT_RELOAD, "Use Proxy", + 10,140,150,19, &last_seq->flag, + 0.0, 21.0, 100, 0, + "Use a preview proxy for this strip"); + + if (last_seq->flag & SEQ_USE_PROXY) { + + + } + + uiBlockEndAlign(block); +} + + +void sequencer_panels() +{ + Sequence *last_seq = get_last_seq(); + int panels = 0; + int type; + + if(last_seq == NULL) { + return; + } + + type = last_seq->type; + + panels = SEQ_PANEL_EDITING; + + if (type == SEQ_MOVIE || type == SEQ_IMAGE || type == SEQ_SCENE + || type == SEQ_HD_SOUND) { + panels |= SEQ_PANEL_INPUT | SEQ_PANEL_FILTER | SEQ_PANEL_PROXY; + } + + if (type == SEQ_RAM_SOUND) { + panels |= SEQ_PANEL_FILTER; + } + + if (type == SEQ_PLUGIN || type >= SEQ_EFFECT) { + panels |= SEQ_PANEL_EFFECT | SEQ_PANEL_PROXY; + } + + if (panels & SEQ_PANEL_EDITING) { + seq_panel_editing(); + } + + if (panels & SEQ_PANEL_INPUT) { + seq_panel_input(); + } + + if (panels & SEQ_PANEL_FILTER) { + if (type == SEQ_RAM_SOUND || type == SEQ_HD_SOUND) { + seq_panel_filter_audio(); + } else { + seq_panel_filter_video(); + } + } + + if (panels & SEQ_PANEL_EFFECT) { + seq_panel_effect(); + } + + if (panels & SEQ_PANEL_PROXY) { + seq_panel_proxy(); + } +} + + +void do_sequencer_panels(unsigned short event) +{ + Sequence *last_seq = get_last_seq(); + + switch(event) { + case B_SEQ_BUT_PLUGIN: + case B_SEQ_BUT_EFFECT: + update_changed_seq_and_deps(last_seq, 0, 1); + break; + + case B_SEQ_BUT_RELOAD: + case B_SEQ_BUT_RELOAD_ALL: + update_seq_ipo_rect(last_seq); + update_seq_icu_rects(last_seq); + + free_imbuf_seq(); // frees all + + break; + case B_SEQ_BUT_TRANSFORM: + calc_sequence(last_seq); + break; + } + + if (event == B_SEQ_BUT_RELOAD_ALL) { + allqueue(REDRAWALL, 0); + } else { + allqueue(REDRAWSEQ, 0); + } +} + /* ************************* SCENE *********************** */ diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index bcc47a7a1ca..b70a62cb65b 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -1052,529 +1052,7 @@ void seq_viewmove(SpaceSeq *sseq) window_set_cursor(win, oldcursor); } -#define SEQ_BUT_PLUGIN 1 -#define SEQ_BUT_RELOAD 2 -#define SEQ_BUT_EFFECT 3 -#define SEQ_BUT_RELOAD_ALL 4 -#define SEQ_BUT_TRANSFORM 5 -void do_seqbuttons(short val) -{ - Sequence *last_seq = get_last_seq(); - - switch(val) { - case SEQ_BUT_PLUGIN: - case SEQ_BUT_EFFECT: - update_changed_seq_and_deps(last_seq, 0, 1); - break; - - case SEQ_BUT_RELOAD: - case SEQ_BUT_RELOAD_ALL: - update_seq_ipo_rect(last_seq); - update_seq_icu_rects(last_seq); - - free_imbuf_seq(); // frees all - - break; - case SEQ_BUT_TRANSFORM: - calc_sequence(last_seq); - break; - } - - if (val == SEQ_BUT_RELOAD_ALL) { - allqueue(REDRAWALL, 0); - } else { - allqueue(REDRAWSEQ, 0); - } -} - -#define SEQ_PANEL_EDITING 1 -#define SEQ_PANEL_INPUT 2 -#define SEQ_PANEL_FILTER 4 -#define SEQ_PANEL_EFFECT 8 -#define SEQ_PANEL_PROXY 16 - -static char* seq_panal_blend_modes() -{ - static char string[2048]; - char formatstring[2048]; - - strcpy(formatstring, "Blend mode: %%t|%s %%x%d|%s %%x%d"); - sprintf(string, formatstring, - "REPLACE", SEQ_BLEND_REPLACE, - "TODO: ALPHA OVER", SEQ_BLEND_ALPHA_OVER); - return string; - -} - -static void seq_panel_editing(short cntrl) -{ - Sequence *last_seq = get_last_seq(); - char * seq_names[] = { "Image", "Meta", "Scene", "Movie", - "Snd RAM", "Snd HD", - "", "Effect" }; - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing", - UI_EMBOSS, UI_HELV, curarea->win); - - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Edit", "Seq", - 10, 230, 318, 204) == 0) return; - - uiDefBut(block, LABEL, - 0, (last_seq->type >= SEQ_EFFECT) ? - "Effect" : seq_names[last_seq->type], - 10,140,60,19, 0, - 0, 0, 0, 0, ""); - - uiDefBut(block, TEX, - B_NOP, "Name: ", - 70,140,180,19, last_seq->name+2, - 0.0, 21.0, 100, 0, ""); - - uiDefButI(block, MENU, SEQ_BUT_RELOAD, seq_panal_blend_modes(), - 10, 120, 120, 19, &last_seq->blend_mode, - 0,0,0,0, "Strip Blend Mode"); - - if (last_seq->blend_mode > 0) { - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Blend:", - 130, 120, 120, 19, &last_seq->blend_opacity, - 0.0, 100.0, 100.0, 0, - "Blend opacity"); - } - - uiDefButBitI(block, TOG, SEQ_MUTE, - SEQ_BUT_RELOAD_ALL, "Mute", - 10,100,60,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Mute the current strip."); - - uiDefButBitI(block, TOG, SEQ_LOCK, - B_NOP, "Lock", - 70,100,60,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Lock strip, so that it can't be transformed."); - - uiDefButBitI(block, TOG, SEQ_IPO_FRAME_LOCKED, - SEQ_BUT_RELOAD_ALL, "IPO Frame locked", - 130,100,120,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Lock the IPO coordinates to the " - "global frame counter."); - - if (!(last_seq->flag & SEQ_LOCK)) { - uiDefButI(block, NUM, - SEQ_BUT_TRANSFORM, "Start", - 10, 80, 120, 20, &last_seq->start, - 0.0, MAXFRAMEF, 0.0, 0.0, "Start of strip"); - uiDefButI(block, NUM, - SEQ_BUT_TRANSFORM, "Chan", - 130, 80, 120, 20, &last_seq->machine, - 0.0, MAXSEQ, 0.0, 0.0, "Channel used (Y position)"); - - if (last_seq->type == SEQ_IMAGE) { - uiDefButI(block, NUM, - SEQ_BUT_TRANSFORM, "Start-Still", - 10, 60, 120, 20, &last_seq->startstill, - 0.0, MAXFRAMEF, 0.0, 0.0, "Start still"); - uiDefButI(block, NUM, - SEQ_BUT_TRANSFORM, "End-Still", - 130, 60, 120, 19, &last_seq->endstill, - 0.0, MAXFRAMEF, 0.0, 0.0, "End still"); - } else { - uiDefButI(block, NUM, - SEQ_BUT_TRANSFORM, "Start-Ofs", - 10, 60, 120, 20, &last_seq->startofs, - 0.0, last_seq->len, 0.0, 0.0, "Start offset"); - uiDefButI(block, NUM, - SEQ_BUT_TRANSFORM, "End-Ofs", - 130, 60, 120, 19, &last_seq->endofs, - 0.0, last_seq->len, 0.0, 0.0, "End offset"); - } - } -} - -static void seq_panel_input(short cntrl) -{ - Sequence *last_seq = get_last_seq(); - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_input", - UI_EMBOSS, UI_HELV, curarea->win); - - uiNewPanelTabbed("Edit", "Seq"); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Input", "Seq", - 10, 230, 318, 204) == 0) return; - - - uiDefButBitI(block, TOG, SEQ_USE_CROP, - SEQ_BUT_RELOAD, "Use Crop", - 10,100,240,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Crop image before processing."); - - if (last_seq->flag & SEQ_USE_CROP) { - if (!last_seq->strip->crop) { - last_seq->strip->crop = - MEM_callocN(sizeof(struct StripCrop), - "StripCrop"); - } - uiDefButI(block, NUM, - SEQ_BUT_RELOAD, "Top", - 10, 80, 120, 20, &last_seq->strip->crop->top, - 0.0, 4096, 0.0, 0.0, "Top of source image"); - uiDefButI(block, NUM, - SEQ_BUT_RELOAD, "Bottom", - 130, 80, 120, 20, &last_seq->strip->crop->bottom, - 0.0, 4096, 0.0, 0.0, "Bottom of source image"); - - uiDefButI(block, NUM, - SEQ_BUT_RELOAD, "Left", - 10, 60, 120, 20, &last_seq->strip->crop->left, - 0.0, 4096, 0.0, 0.0, "Left"); - uiDefButI(block, NUM, - SEQ_BUT_RELOAD, "Right", - 130, 60, 120, 19, &last_seq->strip->crop->right, - 0.0, 4096, 0.0, 0.0, "Right"); - } - - uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, - SEQ_BUT_RELOAD, "Use Translate", - 10,40,240,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Translate image before processing."); - - if (last_seq->flag & SEQ_USE_TRANSFORM) { - if (!last_seq->strip->transform) { - last_seq->strip->transform = - MEM_callocN(sizeof(struct StripTransform), - "StripTransform"); - } - uiDefButI(block, NUM, - SEQ_BUT_RELOAD, "X-Ofs", - 10, 20, 120, 20, &last_seq->strip->transform->xofs, - 0.0, 4096, 0.0, 0.0, "X Offset"); - uiDefButI(block, NUM, - SEQ_BUT_RELOAD, "Y-Ofs", - 130, 20, 120, 20, &last_seq->strip->transform->yofs, - 0.0, 4096, 0.0, 0.0, "Y Offset"); - } - - - uiDefButI(block, NUM, SEQ_BUT_RELOAD, "Preseek:", - 10,0,150,19, &last_seq->anim_preseek, - 0.0, 50.0, 100,0,"On MPEG-seeking preseek this many frames"); - -} - -static void seq_panel_filter_video(short cntrl) -{ - Sequence *last_seq = get_last_seq(); - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter", - UI_EMBOSS, UI_HELV, curarea->win); - - uiNewPanelTabbed("Edit", "Seq"); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Filter", "Seq", - 10, 230, 318, 204) == 0) return; - - - uiBlockBeginAlign(block); - - - uiDefButBitI(block, TOG, SEQ_MAKE_PREMUL, - SEQ_BUT_RELOAD, "Convert to Premul", - 10,110,150,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "Converts RGB values to become premultiplied with Alpha"); - - uiDefButBitI(block, TOG, SEQ_FILTERY, - SEQ_BUT_RELOAD, "FilterY", - 10,90,75,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "For video movies to remove fields"); - - uiDefButBitI(block, TOG, SEQ_MAKE_FLOAT, - SEQ_BUT_RELOAD, "Make Float", - 85,90,75,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "Convert input to float data"); - - uiDefButBitI(block, TOG, SEQ_FLIPX, - SEQ_BUT_RELOAD, "FlipX", - 10,70,75,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "Flip on the X axis"); - uiDefButBitI(block, TOG, SEQ_FLIPY, - SEQ_BUT_RELOAD, "FlipY", - 85,70,75,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "Flip on the Y axis"); - - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:", - 10,50,150,19, &last_seq->mul, - 0.001, 5.0, 100, 0, - "Multiply colors"); - - uiDefButBitI(block, TOG, SEQ_REVERSE_FRAMES, - SEQ_BUT_RELOAD, "Reverse Frames", - 10,30,150,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "Reverse frame order"); - - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:", - 10,10,150,19, &last_seq->strobe, - 1.0, 30.0, 100, 0, - "Only display every nth frame"); - - uiBlockEndAlign(block); - -} - - -static void seq_panel_filter_audio(short cntrl) -{ - Sequence *last_seq = get_last_seq(); - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter", - UI_EMBOSS, UI_HELV, curarea->win); - - uiNewPanelTabbed("Edit", "Seq"); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Filter", "Seq", - 10, 230, 318, 204) == 0) return; - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, ""); - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:", 10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, ""); - uiBlockEndAlign(block); -} - -static void seq_panel_effect(short cntrl) -{ - Sequence *last_seq = get_last_seq(); - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_effect", - UI_EMBOSS, UI_HELV, curarea->win); - - uiNewPanelTabbed("Edit", "Seq"); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Effect", "Seq", - 10, 230, 318, 204) == 0) return; - - if(last_seq->type == SEQ_PLUGIN) { - PluginSeq *pis; - VarStruct *varstr; - int a, xco, yco; - - get_sequence_effect(last_seq);/* make sure, plugin is loaded */ - - pis= last_seq->plugin; - if(pis->vars==0) return; - - varstr= pis->varstr; - if(varstr) { - for(a=0; avars; a++, varstr++) { - xco= 150*(a/6)+10; - yco= 125 - 20*(a % 6)+1; - uiDefBut(block, varstr->type, SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip); - - } - } - return; - } - - uiBlockBeginAlign(block); - - if(last_seq->type==SEQ_WIPE){ - WipeVars *wipe = (WipeVars *)last_seq->effectdata; - char formatstring[256]; - - strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255); - uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring, 10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed"); - uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Blur:", 10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge"); - switch(wipe->wipetype){ /*Skip Types that do not require angle*/ - case DO_IRIS_WIPE: - case DO_CLOCK_WIPE: - break; - - default: - uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:", 10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge"); - } - uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In", 10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe"); - } else if(last_seq->type==SEQ_GLOW){ - GlowVars *glow = (GlowVars *)last_seq->effectdata; - - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:", 10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:", 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:", 10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:", 10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect"); - uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect"); - uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only"); - } - else if(last_seq->type==SEQ_TRANSFORM){ - TransformVars *transform = (TransformVars *)last_seq->effectdata; - - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale Start:", 10,70,150,19, &transform->ScalexIni, 0.0, 10.0, 0, 0, "X Scale Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale End:", 160,70,150,19, &transform->ScalexFin, 0.0, 10.0, 0, 0, "X Scale End"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale Start:", 10,50,150,19, &transform->ScaleyIni, 0.0, 10.0, 0, 0, "Y Scale Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale End:", 160,50,150,19, &transform->ScaleyFin, 0.0, 10.0, 0, 0, "Y Scale End"); - - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Percent", 10, 30, 150, 19, &transform->percent, 0.0, 1.0, 0.0, 0.0, "Percent Translate"); - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Pixels", 160, 30, 150, 19, &transform->percent, 0.0, 0.0, 0.0, 0.0, "Pixels Translate"); - if(transform->percent==1){ - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -500.0, 500.0, 0, 0, "X Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -500.0, 500.0, 0, 0, "X Position End"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -500.0, 500.0, 0, 0, "Y Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -500.0, 500.0, 0, 0, "Y Position End"); - } else { - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -10000.0, 10000.0, 0, 0, "X Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -10000.0, 10000.0, 0, 0, "X Position End"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -10000.0, 10000.0, 0, 0, "Y Position Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -10000.0, 10000.0, 0, 0, "Y Position End"); - - } - - - - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot Start:",10,-30,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start"); - uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot End:",160,-30,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End"); - - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "No Interpolat", 10, -50, 100, 19, &transform->interpolation, 0.0, 0.0, 0.0, 0.0, "No interpolation"); - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Bilinear", 101, -50, 100, 19, &transform->interpolation, 0.0, 1.0, 0.0, 0.0, "Bilinear interpolation"); - uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Bicubic", 202, -50, 100, 19, &transform->interpolation, 0.0, 2.0, 0.0, 0.0, "Bicubic interpolation"); - } else if(last_seq->type==SEQ_COLOR) { - SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata; - uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, ""); - } else if(last_seq->type==SEQ_SPEED){ - SpeedControlVars *sp = - (SpeedControlVars *)last_seq->effectdata; - - uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed"); - - uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE, - SEQ_BUT_RELOAD, - "IPO is velocity", - 10,50,150,19, &sp->flags, - 0.0, 1.0, 0, 0, - "Interpret the IPO value as a " - "velocity instead of a frame number"); - - uiDefButBitI(block, TOG, SEQ_SPEED_BLEND, - SEQ_BUT_RELOAD, - "Enable frame blending", - 10,30,150,19, &sp->flags, - 0.0, 1.0, 0, 0, - "Blend two frames into the " - "target for a smoother result"); - - uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y, - SEQ_BUT_RELOAD, - "IPO value runs from [0..1]", - 10,10,150,19, &sp->flags, - 0.0, 1.0, 0, 0, - "Scale IPO value to get the " - "target frame number."); - } - - uiBlockEndAlign(block); -} - -static void seq_panel_proxy(short cntrl) -{ - Sequence *last_seq = get_last_seq(); - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_proxy", - UI_EMBOSS, UI_HELV, curarea->win); - - uiNewPanelTabbed("Edit", "Seq"); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Proxy", "Seq", - 10, 230, 318, 204) == 0) return; - - uiBlockBeginAlign(block); - - uiDefButBitI(block, TOG, SEQ_USE_PROXY, - SEQ_BUT_RELOAD, "Use Proxy", - 10,140,150,19, &last_seq->flag, - 0.0, 21.0, 100, 0, - "Use a preview proxy for this strip"); - - if (last_seq->flag & SEQ_USE_PROXY) { - - - } - - uiBlockEndAlign(block); -} - - -static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES -{ - Sequence *last_seq = get_last_seq(); - int panels = 0; - int type; - - if(last_seq == NULL) { - uiBlock *block; - block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing", - UI_EMBOSS, UI_HELV, curarea->win); - - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); - uiNewPanel(curarea, block, "Edit", "Seq", - 10, 230, 318, 204); - return; - } - - type = last_seq->type; - - panels = SEQ_PANEL_EDITING; - - if (type == SEQ_MOVIE || type == SEQ_IMAGE || type == SEQ_SCENE - || type == SEQ_HD_SOUND) { - panels |= SEQ_PANEL_INPUT | SEQ_PANEL_FILTER | SEQ_PANEL_PROXY; - } - - if (type == SEQ_RAM_SOUND) { - panels |= SEQ_PANEL_FILTER; - } - - if (type == SEQ_PLUGIN || type >= SEQ_EFFECT) { - panels |= SEQ_PANEL_EFFECT | SEQ_PANEL_PROXY; - } - - if (panels & SEQ_PANEL_EDITING) { - seq_panel_editing(cntrl); - } - - if (panels & SEQ_PANEL_INPUT) { - seq_panel_input(cntrl); - } - - if (panels & SEQ_PANEL_FILTER) { - if (type == SEQ_RAM_SOUND || type == SEQ_HD_SOUND) { - seq_panel_filter_audio(cntrl); - } else { - seq_panel_filter_video(cntrl); - } - } - - if (panels & SEQ_PANEL_EFFECT) { - seq_panel_effect(cntrl); - } - - if (panels & SEQ_PANEL_PROXY) { - seq_panel_proxy(cntrl); - } -} static void seq_blockhandlers(ScrArea *sa) { @@ -1585,13 +1063,6 @@ static void seq_blockhandlers(ScrArea *sa) uiFreeBlocksWin(&sa->uiblocks, sa->win); for(a=0; ablockhandler[a]) { - - case SEQ_HANDLER_PROPERTIES: - seq_panel_properties(sseq->blockhandler[a+1]); - break; - - } /* clear action value for event */ sseq->blockhandler[a+1]= 0; } diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index b97dbac32ec..f1e2f957610 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -899,6 +899,7 @@ void mouse_select_seq(void) recurs_sel_seq(seq); } + allqueue(REDRAWBUTSSCENE, 0); force_draw(0); if(get_last_seq()) allqueue(REDRAWIPO, 0); diff --git a/source/blender/src/header_buttonswin.c b/source/blender/src/header_buttonswin.c index 07a63a46903..4dc1124a8bd 100644 --- a/source/blender/src/header_buttonswin.c +++ b/source/blender/src/header_buttonswin.c @@ -436,6 +436,14 @@ static uiBlock *buts_view_scenemenu(void *arg_unused) uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_DEHLT, "Render|F10", 0, yco-=20, menuwidth, 19, &(G.buts->tab[CONTEXT_SCENE]), (float)TAB_SCENE_RENDER, 0.0, 0, 10, ""); } + + if((G.buts->mainb == CONTEXT_SCENE) && (G.buts->tab[CONTEXT_SCENE]==TAB_SCENE_SEQUENCER)) { + uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_HLT, "Sequencer", + 0, yco-=20, menuwidth, 19, &(G.buts->tab[CONTEXT_SCENE]), (float)TAB_SCENE_SEQUENCER, 0.0, 0, 10, ""); + } else { + uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_DEHLT, "Sequencer", + 0, yco-=20, menuwidth, 19, &(G.buts->tab[CONTEXT_SCENE]), (float)TAB_SCENE_SEQUENCER, 0.0, 0, 10, ""); + } if((G.buts->mainb == CONTEXT_SCENE) && (G.buts->tab[CONTEXT_SCENE]==TAB_SCENE_ANIM)) { uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_HLT, "Animation", @@ -683,6 +691,7 @@ void buts_buttons(void) case CONTEXT_SCENE: uiBlockBeginAlign(block); uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_SCENE, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_RENDER, 0, 0, "Render buttons "); + uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_SEQUENCE, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_SEQUENCER, 0, 0, "Sequencer buttons "); uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_ANIM, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_ANIM, 0, 0, "Anim/playback buttons"); uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_SOUND, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_SOUND, 0, 0, "Sound block buttons"); diff --git a/source/blender/src/header_seq.c b/source/blender/src/header_seq.c index e26ab4a157a..1880484a09f 100644 --- a/source/blender/src/header_seq.c +++ b/source/blender/src/header_seq.c @@ -393,8 +393,7 @@ static void do_seq_editmenu(void *arg, int event) case 3: /* Separate Meta Strip */ un_meta(); break; - case 4: /* Properties... */ - add_blockhandler(curarea, SEQ_HANDLER_PROPERTIES, UI_PNL_UNSTOW); + case 4: /* former Properties... */ break; case 5: /* Duplicate */ add_duplicate_seq(); @@ -450,8 +449,6 @@ static uiBlock *seq_editmenu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "seq_editmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); uiBlockSetButmFunc(block, do_seq_editmenu, NULL); - uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Strip Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Extend from frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Snap to Current Frame|Shift S, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 5415f03701e..486ebfa7010 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4543,9 +4543,6 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } switch(event) { - case UI_BUT_EVENT: - do_seqbuttons(val); - break; case LEFTMOUSE: if(sseq->mainb || view2dmove(event)==0) { @@ -6222,6 +6219,14 @@ void allqueue(unsigned short event, short val) scrarea_queue_headredraw(sa); } break; + case REDRAWSEQ: + if(sa->spacetype==SPACE_SEQ) { + addqueue(sa->win, CHANGED, 1); + scrarea_queue_winredraw(sa); + scrarea_queue_headredraw(sa); + } + /* fall through, since N-keys moved to + Buttons */ case REDRAWBUTSSCENE: if(sa->spacetype==SPACE_BUTS) { buts= sa->spacedata.first; @@ -6294,13 +6299,6 @@ void allqueue(unsigned short event, short val) scrarea_queue_winredraw(sa); } break; - case REDRAWSEQ: - if(sa->spacetype==SPACE_SEQ) { - addqueue(sa->win, CHANGED, 1); - scrarea_queue_winredraw(sa); - scrarea_queue_headredraw(sa); - } - break; case REDRAWOOPS: if(sa->spacetype==SPACE_OOPS) { scrarea_queue_winredraw(sa); From 1b95e2badd42ffab8291358baa70d8e74ad8282b Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 26 Dec 2007 16:15:27 +0000 Subject: [PATCH 54/99] Bugfix, Peach collection: - new "preview" image in material caused crash because copy/paste material didn't support it yet. --- source/blender/src/header_buttonswin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/src/header_buttonswin.c b/source/blender/src/header_buttonswin.c index 4dc1124a8bd..3519c1f582c 100644 --- a/source/blender/src/header_buttonswin.c +++ b/source/blender/src/header_buttonswin.c @@ -170,6 +170,7 @@ void do_buts_buttons(short event) } } matcopybuf.nodetree= ntreeCopyTree(ma->nodetree, 0); + matcopybuf.preview= NULL; matcopied= 1; } break; From 2daf4c978cc889c6056759114a9bdaa53a13c930 Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Wed, 26 Dec 2007 17:04:21 +0000 Subject: [PATCH 55/99] Node curves to maintain handle status after adding a control point Node curves maintain handles status (normal, auto, vector) even after adding a control point now. This makes the behavior the same as in case of removing a control point. Previously the status of handles was reseted. --- source/blender/blenkernel/intern/colortools.c | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 83b014cdd63..e4336576e2a 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -167,18 +167,30 @@ void curvemap_remove(CurveMap *cuma, int flag) void curvemap_insert(CurveMap *cuma, float x, float y) { CurveMapPoint *cmp= MEM_callocN((cuma->totpoint+1)*sizeof(CurveMapPoint), "curve points"); - int a; - - memcpy(cmp, cuma->curve, (cuma->totpoint)*sizeof(CurveMapPoint)); + int a, b, foundloc= 0; + + /* insert fragments of the old one and the new point to the new curve */ + cuma->totpoint++; + for(a=0, b=0; atotpoint; a++) { + if((x < cuma->curve[a].x) && !foundloc) { + cmp[a].x= x; + cmp[a].y= y; + cmp[a].flag= CUMA_SELECT; + foundloc= 1; + } + else { + cmp[a].x= cuma->curve[b].x; + cmp[a].y= cuma->curve[b].y; + cmp[a].flag= cuma->curve[b].flag; + cmp[a].flag &= ~CUMA_SELECT; /* make sure old points don't remain selected */ + cmp[a].shorty= cuma->curve[b].shorty; + b++; + } + } + + /* free old curve and replace it with new one */ MEM_freeN(cuma->curve); cuma->curve= cmp; - - cuma->curve[cuma->totpoint].x= x; - cuma->curve[cuma->totpoint].y= y; - cuma->curve[cuma->totpoint].flag = CUMA_SELECT; - for(a=0; atotpoint; a++, cmp++) - cmp->flag= 0; - cuma->totpoint++; } void curvemap_reset(CurveMap *cuma, rctf *clipr) From e06edeb801b70adbc1d4b98474e7c5d6a930b7b3 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Wed, 26 Dec 2007 19:19:51 +0000 Subject: [PATCH 56/99] == MSVC 7.1 projectfiles == - added missing files to projectfiles - cleaned up thumbnail creation to avoid dependency on BKE_ --- .../blender/blenkernel/BKE_blenkernel.vcproj | 9 +++++++++ projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj | 6 ++++++ projectfiles_vc7/blender/src/BL_src.vcproj | 6 +++--- source/blender/imbuf/intern/thumbs.c | 12 ++++++------ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj index 15614f52fdf..7b7d1ac0608 100644 --- a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj +++ b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj @@ -422,6 +422,12 @@ + + + + @@ -615,6 +621,9 @@ + + diff --git a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj index b42642c774f..8a2b8b95e38 100644 --- a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj +++ b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj @@ -358,6 +358,9 @@ + + @@ -428,6 +431,9 @@ + + diff --git a/projectfiles_vc7/blender/src/BL_src.vcproj b/projectfiles_vc7/blender/src/BL_src.vcproj index 9c03b21f1a8..9d5e40b96b7 100644 --- a/projectfiles_vc7/blender/src/BL_src.vcproj +++ b/projectfiles_vc7/blender/src/BL_src.vcproj @@ -439,9 +439,6 @@ - - @@ -463,6 +460,9 @@ + + diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 131d2ef38f7..718b0537b48 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -27,8 +27,9 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include "BKE_global.h" -#include "BKE_utildefines.h" +/* also defined in BKE_utildefines, repeated here to avoid dependency */ +#define FILE_MAX 240 + #include "BLI_blenlib.h" #include "MEM_guardedalloc.h" @@ -76,18 +77,17 @@ static int get_thumb_dir( char* dir , ThumbSize size) #endif switch(size) { case THB_NORMAL: - strcat(dir, "/.thumbnails/normal"); + strcat(dir, "/.thumbnails/normal/"); break; case THB_LARGE: - strcat(dir, "/.thumbnails/large"); + strcat(dir, "/.thumbnails/large/"); break; case THB_FAIL: - strcat(dir, "/.thumbnails/fail/blender"); + strcat(dir, "/.thumbnails/fail/blender/"); break; default: return 0; /* unknown size */ } - BLI_cleanup_dir(G.sce, dir); return 1; } From 6d13d4473418be180a345df4fb4375f03e7e256c Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Wed, 26 Dec 2007 19:30:49 +0000 Subject: [PATCH 57/99] == Sequencer == Moved status info bar into panels. It was always shown on the wrong place... Added anim-startofs and anim-endofs, so that one can specify the range of _input_ that should be used. There is a subtle difference to start-ofs and end-ofs, which will show, when you use "Reverse Frames" or "Speed Control". Both effects operate on the input-range and _not_ on the display range! Now you can control both in a comfortable way. Only thing missing: a button to copy start-ofs and end-ofs to anim-startofs and anim-endofs. (Andy: that was the feature you missed, when storyboarding with the sequencer and the speed control effect :) Also: added File-Name and Dir-Name to redirect input as needed. --- source/blender/include/BSE_sequence.h | 1 + source/blender/include/butspace.h | 1 + source/blender/makesdna/DNA_sequence_types.h | 7 +- source/blender/src/buttons_scene.c | 131 ++++++++++++++++- source/blender/src/drawseq.c | 139 ------------------- source/blender/src/sequence.c | 61 +++++++- 6 files changed, 191 insertions(+), 149 deletions(-) diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 7bdf16e8e90..46e0aa6ff1f 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -60,6 +60,7 @@ void build_seqar_cb(struct ListBase *seqbase, struct Sequence ***seqar, void free_editing(struct Editing *ed); void calc_sequence(struct Sequence *seq); void calc_sequence_disp(struct Sequence *seq); +void reload_sequence_new_file(struct Sequence * seq); void sort_seq(void); void clear_scene_in_allseqs(struct Scene *sce); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 7eabc367782..4de9064b0bd 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -355,6 +355,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_SEQ_BUT_EFFECT 1693 #define B_SEQ_BUT_RELOAD_ALL 1694 #define B_SEQ_BUT_TRANSFORM 1695 +#define B_SEQ_BUT_RELOAD_FILE 1696 /* *********************** */ #define B_ARMATUREBUTS 1800 diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index db3790e6ea3..b401ee05433 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -119,7 +119,6 @@ typedef struct Sequence { char name[24]; /* name, not set by default and dosnt need to be unique as with ID's */ int flag, type; /*flags bitmap (see below) and the type of sequence*/ - int pad; int len; /* the length of the contense of this strip - before handles are applied */ int start, startofs, endofs; int startstill, endstill; @@ -128,6 +127,7 @@ typedef struct Sequence { float mul, handsize; /* is sfra needed anymore? - it looks like its only used in one place */ int sfra; /* starting frame according to the timeline of the scene. */ + int anim_preseek; Strip *strip; @@ -151,10 +151,11 @@ typedef struct Sequence { void *effectdata; /* Struct pointer for effect settings */ - int anim_preseek; + int anim_startofs; /* only use part of animation file */ + int anim_endofs; /* is subtle different to startofs / endofs */ + int blend_mode; float blend_opacity; - int pad2; } Sequence; typedef struct MetaStack { diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index b6b8805ba5c..5c9cacdb2fc 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -500,6 +500,10 @@ static void seq_panel_editing() "Snd RAM", "Snd HD", "", "Effect" }; uiBlock *block; + static char strdata[1024]; + char * str = strdata; + char * p; + int yco; block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing", UI_EMBOSS, UI_HELV, curarea->win); @@ -578,6 +582,90 @@ static void seq_panel_editing() 0.0, last_seq->len, 0.0, 0.0, "End offset"); } } + + + if(last_seq->type & SEQ_EFFECT) + sprintf(str, "Len: %d\nFrom %d - %d\n", last_seq->len, last_seq->startdisp, last_seq->enddisp-1); + else + sprintf(str, "Len: %d(%d)\n", last_seq->enddisp-last_seq->startdisp, last_seq->len); + + str += strlen(str); + + if(last_seq->type==SEQ_IMAGE) { + if (last_seq->len > 1) { + /* CURRENT */ + StripElem * se= give_stripelem(last_seq, CFRA); + StripElem * last; + + /* FIRST AND LAST */ + + if(last_seq->strip) { + se= last_seq->strip->stripdata; + last= se+last_seq->len-1; + if(last_seq->startofs) se+= last_seq->startofs; + if(last_seq->endofs) last-= last_seq->endofs; + + sprintf(str, "First: %s at %d\nLast: %s at %d\n", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1); + } + } else { /* single image */ + if (last_seq->strip) { + sprintf(str, "Len: %d\n", last_seq->enddisp-last_seq->startdisp); + } + } + + str += strlen(str); + + /* orig size */ + if(last_seq->strip) { + sprintf(str, "OrigSize: %d x %d\n", last_seq->strip->orx, last_seq->strip->ory); + } + } + else if(last_seq->type==SEQ_MOVIE) { + int sta= last_seq->startofs; + int end= last_seq->len-1-last_seq->endofs; + + sprintf(str, "First: %d at %d\nLast: %d at %d\nCur: %d\n", + sta, last_seq->startdisp, end, last_seq->enddisp-1, + (G.scene->r.cfra)-last_seq->startdisp); + } + else if(last_seq->type==SEQ_SCENE) { + TStripElem * se= give_tstripelem(last_seq, (G.scene->r.cfra)); + if(se && last_seq->scene) { + sprintf(str, "First: %d\nLast: %d\nCur: %d\n", last_seq->sfra+se->nr, last_seq->sfra, last_seq->sfra+last_seq->len-1); + } + } + else if(last_seq->type==SEQ_RAM_SOUND + || last_seq->type == SEQ_HD_SOUND) { + + int sta= last_seq->startofs; + int end= last_seq->len-1-last_seq->endofs; + + sprintf(str, "First: %d at %d\nLast: %d at %d\nCur: %d\n", + sta, last_seq->startdisp, end, last_seq->enddisp-1, + (G.scene->r.cfra)-last_seq->startdisp); + } + else if(last_seq->type == SEQ_SPEED) { + SpeedControlVars * vars = + (SpeedControlVars*) last_seq->effectdata; + + if (vars) { + sprintf(str, "Last mapped frame: %d at %d\n", + vars->lastValidFrame, + vars->lastValidFrame + + last_seq->startdisp); + } + } + + str = strdata; + yco = 40; + + while ((p = strchr(str, '\n'))) { + *p = 0; + uiDefBut(block, LABEL, 0, str, 10,yco,240,19, 0, + 0, 0, 0, 0, ""); + str = p+1; + yco -= 20; + } } static void seq_panel_input() @@ -590,7 +678,30 @@ static void seq_panel_input() if(uiNewPanel(curarea, block, "Input", "Sequencer", 10, 230, 318, 204) == 0) return; - + uiDefBut(block, TEX, + B_SEQ_BUT_RELOAD_FILE, "Dir: ", + 10,140,240,19, last_seq->strip->dir, + 0.0, 160.0, 100, 0, ""); + + if (last_seq->type == SEQ_IMAGE) { + StripElem * se = give_stripelem(last_seq, CFRA); + + if (se) { + uiDefBut(block, TEX, + B_SEQ_BUT_RELOAD_FILE, "File: ", + 10, 120, 240,19, se->name, + 0.0, 80.0, 100, 0, ""); + } + + } else if (last_seq->type == SEQ_MOVIE || + last_seq->type == SEQ_HD_SOUND || + last_seq->type == SEQ_RAM_SOUND) { + uiDefBut(block, TEX, + B_SEQ_BUT_RELOAD_FILE, "File: ", + 10,120,240,19, last_seq->strip->stripdata->name, + 0.0, 80.0, 100, 0, ""); + } + uiDefButBitI(block, TOG, SEQ_USE_CROP, B_SEQ_BUT_RELOAD, "Use Crop", 10,100,240,19, &last_seq->flag, @@ -645,8 +756,18 @@ static void seq_panel_input() } - uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "Preseek:", - 10,0,150,19, &last_seq->anim_preseek, + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD_FILE, "A-Start", + 10, 0, 120, 20, &last_seq->anim_startofs, + 0.0, MAXFRAMEF, 0.0, 0.0, "Animation start offset in file"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD_FILE, "A-End", + 130, 0, 120, 20, &last_seq->anim_endofs, + 0.0, MAXFRAMEF, 0.0, 0.0, "Animation end offset in file"); + + + uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "MPEG-Preseek:", + 10, -20, 240,19, &last_seq->anim_preseek, 0.0, 50.0, 100,0,"On MPEG-seeking preseek this many frames"); } @@ -948,7 +1069,9 @@ void do_sequencer_panels(unsigned short event) case B_SEQ_BUT_EFFECT: update_changed_seq_and_deps(last_seq, 0, 1); break; - + case B_SEQ_BUT_RELOAD_FILE: + reload_sequence_new_file(last_seq); + break; case B_SEQ_BUT_RELOAD: case B_SEQ_BUT_RELOAD_ALL: update_seq_ipo_rect(last_seq); diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index b70a62cb65b..156a6c7b6c9 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -861,143 +861,6 @@ static void draw_image_seq(ScrArea *sa) sa->win_swap= WIN_BACK_OK; } -static void draw_extra_seqinfo(void) -{ - Sequence *last_seq = get_last_seq(); - StripElem *se, *last; - float xco, xfac, yco, yfac; - int sta, end; - char str[256]; - - if(last_seq==0) return; - - /* xfac: size of 1 pixel */ - xfac= G.v2d->cur.xmax - G.v2d->cur.xmin; - xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin); - xco= G.v2d->cur.xmin+10*xfac; - - yfac= G.v2d->cur.ymax - G.v2d->cur.ymin; - yfac/= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin); - yco= G.v2d->cur.ymin+40*yfac; - - BIF_ThemeColor(TH_TEXT_HI); - - /* NAME */ - glRasterPos3f(xco, yco, 0.0); - strncpy(str, give_seqname(last_seq), 255); - BMF_DrawString(G.font, str); - xco += xfac*BMF_GetStringWidth(G.font, str) +10.0*xfac; - - if(last_seq->type==SEQ_SCENE && last_seq->scene) { - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, last_seq->scene->id.name+2); - xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac; - } - - /* LEN, dont bother with single images */ - if (check_single_seq(last_seq)==0) { - if(last_seq->type & SEQ_EFFECT) - sprintf(str, "len: %d From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1); - else - sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len); - - glRasterPos3f(xco, yco, 0.0); - - BMF_DrawString(G.font, str); - xco += xfac*BMF_GetStringWidth(G.font, str) +10.0*xfac; - } - - - if(last_seq->type==SEQ_IMAGE) { - if (last_seq->len > 1) { - /* CURRENT */ - se= give_stripelem(last_seq, (G.scene->r.cfra)); - if(se) { - sprintf(str, "Cur: %s%s", last_seq->strip->dir, se->name); - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - xco += xfac*BMF_GetStringWidth(G.font, str) +10.0*xfac; - } - - /* FIRST AND LAST */ - - if(last_seq->strip) { - se= last_seq->strip->stripdata; - last= se+last_seq->len-1; - if(last_seq->startofs) se+= last_seq->startofs; - if(last_seq->endofs) last-= last_seq->endofs; - - sprintf(str, "First: %s at %d Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1); - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; - } - } else { /* single image */ - if (last_seq->strip) { - sprintf(str, "Single: %s%s len: %d", last_seq->strip->dir, last_seq->strip->stripdata->name, last_seq->enddisp-last_seq->startdisp); - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; - } - } - /* orig size */ - if(last_seq->strip) { - sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory); - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac; - } - } - else if(last_seq->type==SEQ_MOVIE) { - - sta= last_seq->startofs; - end= last_seq->len-1-last_seq->endofs; - - sprintf(str, "%s %s%s First: %d at %d Last: %d at %d Cur: %d", - last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name, - sta, last_seq->startdisp, end, last_seq->enddisp-1, (G.scene->r.cfra)-last_seq->startdisp); - - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - } - else if(last_seq->type==SEQ_SCENE) { - TStripElem * se= give_tstripelem(last_seq, (G.scene->r.cfra)); - if(se && last_seq->scene) { - sprintf(str, "Cur: %d First: %d Last: %d", last_seq->sfra+se->nr, last_seq->sfra, last_seq->sfra+last_seq->len-1); - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - } - } - else if(last_seq->type==SEQ_RAM_SOUND - || last_seq->type == SEQ_HD_SOUND) { - - sta= last_seq->startofs; - end= last_seq->len-1-last_seq->endofs; - - sprintf(str, "%s %s%s First: %d at %d Last: %d at %d Cur: %d Gain: %.2f dB Pan: %.2f", - last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name, - sta, last_seq->startdisp, end, last_seq->enddisp-1, (G.scene->r.cfra)-last_seq->startdisp, - last_seq->level, last_seq->pan); - - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - } - else if(last_seq->type == SEQ_SPEED) { - SpeedControlVars * vars = - (SpeedControlVars*) last_seq->effectdata; - - if (vars) { - sprintf(str, "Last mapped frame: %d at %d", - vars->lastValidFrame, - vars->lastValidFrame - + last_seq->startdisp); - - glRasterPos3f(xco, yco, 0.0); - BMF_DrawString(G.font, str); - } - } -} - void seq_reset_imageofs(SpaceSeq *sseq) { sseq->xof = sseq->yof = sseq->zoom = 0; @@ -1200,8 +1063,6 @@ void drawseqspace(ScrArea *sa, void *spacedata) } } - draw_extra_seqinfo(); - /* Draw markers */ draw_markers_timespace(1); diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 5faffb38107..3d7ac3021a1 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -132,7 +132,10 @@ void free_strip(Strip *strip) void new_tstripdata(Sequence *seq) { if(seq->strip) { - free_tstripdata(seq->strip->len, seq->strip->tstripdata); + if (seq->strip->tstripdata) { + free_tstripdata(seq->strip->len, + seq->strip->tstripdata); + } seq->strip->tstripdata= 0; seq->strip->len= seq->len; } @@ -372,6 +375,58 @@ void calc_sequence(Sequence *seq) } } +void reload_sequence_new_file(Sequence * seq) +{ + char str[FILE_MAXDIR+FILE_MAXFILE]; + + if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE || + seq->type == SEQ_HD_SOUND)) { + return; + } + + new_tstripdata(seq); + + if (seq->type == SEQ_IMAGE) { + return; + } + + strncpy(str, seq->strip->dir, FILE_MAXDIR-1); + strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1); + + if (seq->type == SEQ_MOVIE) { + if(seq->anim) IMB_free_anim(seq->anim); + seq->anim = openanim(str, IB_rect); + + if (!seq->anim) { + return; + } + + seq->len = IMB_anim_get_duration(seq->anim); + + seq->anim_preseek = IMB_anim_get_preseek(seq->anim); + + seq->len -= seq->anim_startofs; + seq->len -= seq->anim_endofs; + if (seq->len < 0) { + seq->len = 0; + } + seq->strip->len = seq->len; + } else if (seq->type == SEQ_HD_SOUND) { + if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio); + seq->hdaudio = sound_open_hdaudio(str); + + if (!seq->hdaudio) { + return; + } + + seq->strip->len = seq->len + = sound_hdaudio_get_duration(seq->hdaudio, FPS); + } + + + calc_sequence(seq); +} + void sort_seq() { /* all strips together per kind, and in order of y location ("machine") */ @@ -685,7 +740,7 @@ StripElem *give_stripelem(Sequence *seq, int cfra) if (nr == -1) return 0; if (se == 0) return 0; - se += nr; + se += nr + seq->anim_startofs; return se; } @@ -991,7 +1046,7 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) } if(seq->anim) { IMB_anim_set_preseek(seq->anim, seq->anim_preseek); - se->ibuf = IMB_anim_absolute(seq->anim, se->nr); + se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs); } if(se->ibuf == 0) { From 8e84f64c3daa5cd2cafc7fd14d7d0fad472298cf Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 26 Dec 2007 20:43:58 +0000 Subject: [PATCH 58/99] == Multires == Fixed multires_update_colors so it ignores the editmesh during render. --- source/blender/blenkernel/intern/multires.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 2a9ac65b083..c402d59f2c0 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -856,11 +856,10 @@ static void multires_update_faces(Mesh *me, EditMesh *em) if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); } -void multires_update_colors(Mesh *me) +static void multires_update_colors(Mesh *me, EditMesh *em) { MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); MultiresCol *pr_deltas= NULL, *cr_deltas= NULL; - EditMesh *em= G.obedit ? G.editMesh : NULL; CustomData *src= em ? &em->fdata : &me->fdata; EditFace *efa= NULL; unsigned i,j,curf= 0; @@ -961,7 +960,7 @@ void multires_update_levels(Mesh *me, const int render) multires_update_first_level(me, em); multires_update_vertices(me, em); multires_update_faces(me, em); - multires_update_colors(me); + multires_update_colors(me, em); } static void check_colors(Mesh *me) From ae976e087a7110c6b25a0fee4f663185b5e4319d Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Wed, 26 Dec 2007 21:46:30 +0000 Subject: [PATCH 59/99] This is patch: [#7975] imbuf for DDS textures: improved read support and a few bugs fixed Kent Notes From the author: The attached patch syncs the DDS code in Blender with the latest revision (324) of the nvidia texture tools. This fixes a few minor issues and adds support for a more types of DDS textures, in particular uncompressed textures that don't have the standard 16, 24, or 32 bits per pixel. Note: I have started using the nvidia texture tools convention for naming integer types (uint, uint16, uint8, uint64 etc.) because doing so makes it much easier to merge patches from upstream. Since the code is compiled separately from the rest of Blender, this likely does not pose a problem. However, if there turns out to be a good reason for avoiding those nvidia type names from upstream, I'd be happy to fix it. Regards, Amorilia --- source/blender/imbuf/intern/dds/BlockDXT.cpp | 172 ++++-- source/blender/imbuf/intern/dds/BlockDXT.h | 79 ++- .../blender/imbuf/intern/dds/ColorBlock.cpp | 67 +- source/blender/imbuf/intern/dds/ColorBlock.h | 23 +- source/blender/imbuf/intern/dds/Common.h | 18 +- .../imbuf/intern/dds/DirectDrawSurface.cpp | 582 ++++++++++-------- .../imbuf/intern/dds/DirectDrawSurface.h | 111 ++-- source/blender/imbuf/intern/dds/Image.cpp | 14 +- source/blender/imbuf/intern/dds/Image.h | 29 +- source/blender/imbuf/intern/dds/PixelFormat.h | 110 ++++ 10 files changed, 771 insertions(+), 434 deletions(-) create mode 100644 source/blender/imbuf/intern/dds/PixelFormat.h diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp index 5290a677678..24a090d93f6 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.cpp +++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp @@ -64,7 +64,7 @@ BlockDXT1 ----------------------------------------------------------------------------*/ -unsigned int BlockDXT1::evaluatePalette(Color32 color_array[4]) const +uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const { // Does bit expansion before interpolation. color_array[0].b = (col0.b << 3) | (col0.b >> 2); @@ -179,9 +179,9 @@ void BlockDXT1::decodeBlock(ColorBlock * block) const evaluatePalette(color_array); // Write color block. - for( unsigned int j = 0; j < 4; j++ ) { - for( unsigned int i = 0; i < 4; i++ ) { - unsigned int idx = (row[j] >> (2 * i)) & 3; + for( uint j = 0; j < 4; j++ ) { + for( uint i = 0; i < 4; i++ ) { + uint idx = (row[j] >> (2 * i)) & 3; block->color(i, j) = color_array[idx]; } } @@ -190,7 +190,7 @@ void BlockDXT1::decodeBlock(ColorBlock * block) const void BlockDXT1::setIndices(int * idx) { indices = 0; - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { indices |= (idx[i] & 3) << (2 * i); } } @@ -199,16 +199,14 @@ void BlockDXT1::setIndices(int * idx) /// Flip DXT1 block vertically. inline void BlockDXT1::flip4() { - unsigned char tmp; - swap(row[0], row[3], tmp); - swap(row[1], row[2], tmp); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half DXT1 block vertically. inline void BlockDXT1::flip2() { - unsigned char tmp; - swap(row[0], row[1], tmp); + swap(row[0], row[1]); } @@ -248,16 +246,14 @@ void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const /// Flip DXT3 alpha block vertically. void AlphaBlockDXT3::flip4() { - unsigned short tmp; - swap(row[0], row[3], tmp); - swap(row[1], row[2], tmp); + swap(row[0], row[3]); + swap(row[1], row[2]); } /// Flip half DXT3 alpha block vertically. void AlphaBlockDXT3::flip2() { - unsigned short tmp; - swap(row[0], row[1], tmp); + swap(row[0], row[1]); } /// Flip DXT3 block vertically. @@ -279,7 +275,7 @@ void BlockDXT3::flip2() BlockDXT5 ----------------------------------------------------------------------------*/ -void AlphaBlockDXT5::evaluatePalette(unsigned char alpha[8]) const +void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const { if (alpha0 > alpha1) { evaluatePalette8(alpha); @@ -289,35 +285,35 @@ void AlphaBlockDXT5::evaluatePalette(unsigned char alpha[8]) const } } -void AlphaBlockDXT5::evaluatePalette8(unsigned char alpha[8]) const +void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const { // 8-alpha block: derive the other six alphas. // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. alpha[0] = alpha0; alpha[1] = alpha1; - alpha[2] = (6 * alpha0 + 1 * alpha1) / 7; // bit code 010 - alpha[3] = (5 * alpha0 + 2 * alpha1) / 7; // bit code 011 - alpha[4] = (4 * alpha0 + 3 * alpha1) / 7; // bit code 100 - alpha[5] = (3 * alpha0 + 4 * alpha1) / 7; // bit code 101 - alpha[6] = (2 * alpha0 + 5 * alpha1) / 7; // bit code 110 - alpha[7] = (1 * alpha0 + 6 * alpha1) / 7; // bit code 111 + alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7; // bit code 010 + alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; // bit code 011 + alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; // bit code 100 + alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; // bit code 101 + alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; // bit code 110 + alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7; // bit code 111 } -void AlphaBlockDXT5::evaluatePalette6(unsigned char alpha[8]) const +void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const { // 6-alpha block. // Bit code 000 = alpha0, 001 = alpha1, others are interpolated. alpha[0] = alpha0; alpha[1] = alpha1; - alpha[2] = (4 * alpha0 + 1 * alpha1) / 5; // Bit code 010 - alpha[3] = (3 * alpha0 + 2 * alpha1) / 5; // Bit code 011 - alpha[4] = (2 * alpha0 + 3 * alpha1) / 5; // Bit code 100 - alpha[5] = (1 * alpha0 + 4 * alpha1) / 5; // Bit code 101 + alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5; // Bit code 010 + alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; // Bit code 011 + alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; // Bit code 100 + alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5; // Bit code 101 alpha[6] = 0x00; // Bit code 110 alpha[7] = 0xFF; // Bit code 111 } -void AlphaBlockDXT5::indices(unsigned char index_array[16]) const +void AlphaBlockDXT5::indices(uint8 index_array[16]) const { index_array[0x0] = bits0; index_array[0x1] = bits1; @@ -337,52 +333,52 @@ void AlphaBlockDXT5::indices(unsigned char index_array[16]) const index_array[0xF] = bitsF; } -unsigned int AlphaBlockDXT5::index(unsigned int index) const +uint AlphaBlockDXT5::index(uint index) const { int offset = (3 * index + 16); - return (this->u >> offset) & 0x7; + return uint((this->u >> offset) & 0x7); } -void AlphaBlockDXT5::setIndex(unsigned int index, unsigned int value) +void AlphaBlockDXT5::setIndex(uint index, uint value) { int offset = (3 * index + 16); - unsigned long long mask = ((unsigned long long)(0x7)) << offset; - this->u = (this->u & ~mask) | (((unsigned long long)(value)) << offset); + uint64 mask = uint64(0x7) << offset; + this->u = (this->u & ~mask) | (uint64(value) << offset); } void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const { - unsigned char alpha_array[8]; + uint8 alpha_array[8]; evaluatePalette(alpha_array); - unsigned char index_array[16]; + uint8 index_array[16]; indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { block->color(i).a = alpha_array[index_array[i]]; } } void AlphaBlockDXT5::flip4() { - unsigned long long * b = (unsigned long long *)this; + uint64 * b = (uint64 *)this; // @@ The masks might have to be byte swapped. - unsigned long long tmp = (*b & (unsigned long long)(0x000000000000FFFFLL)); - tmp |= (*b & (unsigned long long)(0x000000000FFF0000LL)) << 36; - tmp |= (*b & (unsigned long long)(0x000000FFF0000000LL)) << 12; - tmp |= (*b & (unsigned long long)(0x000FFF0000000000LL)) >> 12; - tmp |= (*b & (unsigned long long)(0xFFF0000000000000LL)) >> 36; + uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL)); + tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36; + tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12; + tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12; + tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36; *b = tmp; } void AlphaBlockDXT5::flip2() { - unsigned int * b = (unsigned int *)this; + uint * b = (uint *)this; // @@ The masks might have to be byte swapped. - unsigned int tmp = (*b & 0xFF000000); + uint tmp = (*b & 0xFF000000); tmp |= (*b & 0x00000FFF) << 12; tmp |= (*b & 0x00FFF000) >> 12; @@ -396,6 +392,7 @@ void BlockDXT5::decodeBlock(ColorBlock * block) const // Decode alpha. alpha.decodeBlock(block); + } /// Flip DXT5 block vertically. @@ -416,13 +413,13 @@ void BlockDXT5::flip2() /// Decode ATI1 block. void BlockATI1::decodeBlock(ColorBlock * block) const { - unsigned char alpha_array[8]; + uint8 alpha_array[8]; alpha.evaluatePalette(alpha_array); - unsigned char index_array[16]; + uint8 index_array[16]; alpha.indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { Color32 & c = block->color(i); c.b = c.g = c.r = alpha_array[index_array[i]]; c.a = 255; @@ -445,13 +442,13 @@ void BlockATI1::flip2() /// Decode ATI2 block. void BlockATI2::decodeBlock(ColorBlock * block) const { - unsigned char alpha_array[8]; - unsigned char index_array[16]; + uint8 alpha_array[8]; + uint8 index_array[16]; x.evaluatePalette(alpha_array); x.indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { Color32 & c = block->color(i); c.r = alpha_array[index_array[i]]; } @@ -459,7 +456,7 @@ void BlockATI2::decodeBlock(ColorBlock * block) const y.evaluatePalette(alpha_array); y.indices(index_array); - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { Color32 & c = block->color(i); c.g = alpha_array[index_array[i]]; c.b = 0; @@ -481,6 +478,68 @@ void BlockATI2::flip2() y.flip2(); } + +void BlockCTX1::evaluatePalette(Color32 color_array[4]) const +{ + // Does bit expansion before interpolation. + color_array[0].b = 0x00; + color_array[0].g = col0[1]; + color_array[0].r = col0[0]; + color_array[0].a = 0xFF; + + color_array[1].r = 0x00; + color_array[1].g = col0[1]; + color_array[1].b = col1[0]; + color_array[1].a = 0xFF; + + color_array[2].r = 0x00; + color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; + color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; + color_array[2].a = 0xFF; + + color_array[3].r = 0x00; + color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; + color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; + color_array[3].a = 0xFF; +} + +void BlockCTX1::decodeBlock(ColorBlock * block) const +{ + // Decode color block. + Color32 color_array[4]; + evaluatePalette(color_array); + + // Write color block. + for( uint j = 0; j < 4; j++ ) { + for( uint i = 0; i < 4; i++ ) { + uint idx = (row[j] >> (2 * i)) & 3; + block->color(i, j) = color_array[idx]; + } + } +} + +void BlockCTX1::setIndices(int * idx) +{ + indices = 0; + for(uint i = 0; i < 16; i++) { + indices |= (idx[i] & 3) << (2 * i); + } +} + + +/// Flip CTX1 block vertically. +inline void BlockCTX1::flip4() +{ + swap(row[0], row[3]); + swap(row[1], row[2]); +} + +/// Flip half CTX1 block vertically. +inline void BlockCTX1::flip2() +{ + swap(row[0], row[1]); +} + void mem_read(Stream & mem, BlockDXT1 & block) { mem_read(mem, block.col0.u); @@ -521,3 +580,12 @@ void mem_read(Stream & mem, BlockATI2 & block) mem_read(mem, block.y); } +void mem_read(Stream & mem, BlockCTX1 & block) +{ + mem_read(mem, block.col0[0]); + mem_read(mem, block.col0[1]); + mem_read(mem, block.col1[0]); + mem_read(mem, block.col1[1]); + mem_read(mem, block.indices); +} + diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h index 1f710360c3c..5c232201f0c 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -58,6 +58,7 @@ #ifndef _DDS_BLOCKDXT_H #define _DDS_BLOCKDXT_H +#include #include #include #include @@ -68,14 +69,14 @@ struct BlockDXT1 Color16 col0; Color16 col1; union { - unsigned char row[4]; - unsigned int indices; + uint8 row[4]; + uint indices; }; bool isFourColorMode() const; - unsigned int evaluatePalette(Color32 color_array[4]) const; - unsigned int evaluatePaletteFast(Color32 color_array[4]) const; + uint evaluatePalette(Color32 color_array[4]) const; + uint evaluatePaletteFast(Color32 color_array[4]) const; void evaluatePalette3(Color32 color_array[4]) const; void evaluatePalette4(Color32 color_array[4]) const; @@ -90,7 +91,7 @@ struct BlockDXT1 /// Return true if the block uses four color mode, false otherwise. inline bool BlockDXT1::isFourColorMode() const { - return col0.u >= col1.u; // @@ > or >= ? + return col0.u > col1.u; } @@ -99,24 +100,24 @@ struct AlphaBlockDXT3 { union { struct { - unsigned int alpha0 : 4; - unsigned int alpha1 : 4; - unsigned int alpha2 : 4; - unsigned int alpha3 : 4; - unsigned int alpha4 : 4; - unsigned int alpha5 : 4; - unsigned int alpha6 : 4; - unsigned int alpha7 : 4; - unsigned int alpha8 : 4; - unsigned int alpha9 : 4; - unsigned int alphaA : 4; - unsigned int alphaB : 4; - unsigned int alphaC : 4; - unsigned int alphaD : 4; - unsigned int alphaE : 4; - unsigned int alphaF : 4; + uint alpha0 : 4; + uint alpha1 : 4; + uint alpha2 : 4; + uint alpha3 : 4; + uint alpha4 : 4; + uint alpha5 : 4; + uint alpha6 : 4; + uint alpha7 : 4; + uint alpha8 : 4; + uint alpha9 : 4; + uint alphaA : 4; + uint alphaB : 4; + uint alphaC : 4; + uint alphaD : 4; + uint alphaE : 4; + uint alphaF : 4; }; - unsigned short row[4]; + uint16 row[4]; }; void decodeBlock(ColorBlock * block) const; @@ -163,16 +164,16 @@ struct AlphaBlockDXT5 unsigned int bitsE : 3; // 45 - 61 unsigned int bitsF : 3; // 48 - 64 }; - unsigned long long u; + uint64 u; }; - void evaluatePalette(unsigned char alpha[8]) const; - void evaluatePalette8(unsigned char alpha[8]) const; - void evaluatePalette6(unsigned char alpha[8]) const; - void indices(unsigned char index_array[16]) const; + void evaluatePalette(uint8 alpha[8]) const; + void evaluatePalette8(uint8 alpha[8]) const; + void evaluatePalette6(uint8 alpha[8]) const; + void indices(uint8 index_array[16]) const; - unsigned int index(unsigned int index) const; - void setIndex(unsigned int index, unsigned int value); + uint index(uint index) const; + void setIndex(uint index, uint value); void decodeBlock(ColorBlock * block) const; @@ -216,6 +217,25 @@ struct BlockATI2 void flip2(); }; +/// CTX1 block. +struct BlockCTX1 +{ + uint8 col0[2]; + uint8 col1[2]; + union { + uint8 row[4]; + uint indices; + }; + + void evaluatePalette(Color32 color_array[4]) const; + void setIndices(int * idx); + + void decodeBlock(ColorBlock * block) const; + + void flip4(); + void flip2(); +}; + void mem_read(Stream & mem, BlockDXT1 & block); void mem_read(Stream & mem, AlphaBlockDXT3 & block); void mem_read(Stream & mem, BlockDXT3 & block); @@ -223,5 +243,6 @@ void mem_read(Stream & mem, AlphaBlockDXT5 & block); void mem_read(Stream & mem, BlockDXT5 & block); void mem_read(Stream & mem, BlockATI1 & block); void mem_read(Stream & mem, BlockATI2 & block); +void mem_read(Stream & mem, BlockCTX1 & block); #endif // _DDS_BLOCKDXT_H diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp index 63997f93c8c..0199d15ada7 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.cpp +++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp @@ -39,13 +39,13 @@ #include // Get approximate luminance. - inline static unsigned int colorLuminance(Color32 c) + inline static uint colorLuminance(Color32 c) { return c.r + c.g + c.b; } // Get the euclidean distance between the given colors. - inline static unsigned int colorDistance(Color32 c0, Color32 c1) + inline static uint colorDistance(Color32 c0, Color32 c1) { return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b); } @@ -59,22 +59,22 @@ ColorBlock::ColorBlock() /// Init the color block with the contents of the given block. ColorBlock::ColorBlock(const ColorBlock & block) { - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { color(i) = block.color(i); } } /// Initialize this color block. -ColorBlock::ColorBlock(const Image * img, unsigned int x, unsigned int y) +ColorBlock::ColorBlock(const Image * img, uint x, uint y) { init(img, x, y); } -void ColorBlock::init(const Image * img, unsigned int x, unsigned int y) +void ColorBlock::init(const Image * img, uint x, uint y) { - const unsigned int bw = min(img->width() - x, 4U); - const unsigned int bh = min(img->height() - y, 4U); + const uint bw = min(img->width() - x, 4U); + const uint bh = min(img->height() - y, 4U); static int remainder[] = { 0, 0, 0, 0, @@ -86,10 +86,10 @@ void ColorBlock::init(const Image * img, unsigned int x, unsigned int y) // Blocks that are smaller than 4x4 are handled by repeating the pixels. // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :( - for(unsigned int i = 0; i < 4; i++) { + for(uint i = 0; i < 4; i++) { //const int by = i % bh; const int by = remainder[(bh - 1) * 4 + i]; - for(unsigned int e = 0; e < 4; e++) { + for(uint e = 0; e < 4; e++) { //const int bx = e % bw; const int bx = remainder[(bw - 1) * 4 + e]; color(e, i) = img->pixel(x + bx, y + by); @@ -111,7 +111,7 @@ void ColorBlock::splatX() { for(int i = 0; i < 16; i++) { - unsigned char x = m_color[i].r; + uint8 x = m_color[i].r; m_color[i] = Color32(x, x, x, x); } } @@ -120,16 +120,16 @@ void ColorBlock::splatY() { for(int i = 0; i < 16; i++) { - unsigned char y = m_color[i].g; + uint8 y = m_color[i].g; m_color[i] = Color32(y, y, y, y); } } /// Count number of unique colors in this color block. -unsigned int ColorBlock::countUniqueColors() const +uint ColorBlock::countUniqueColors() const { - unsigned int count = 0; + uint count = 0; // @@ This does not have to be o(n^2) for(int i = 0; i < 16; i++) @@ -152,17 +152,27 @@ unsigned int ColorBlock::countUniqueColors() const /// Get average color of the block. Color32 ColorBlock::averageColor() const { - unsigned int r, g, b, a; + uint r, g, b, a; r = g = b = a = 0; - for(unsigned int i = 0; i < 16; i++) { + for(uint i = 0; i < 16; i++) { r += m_color[i].r; g += m_color[i].g; b += m_color[i].b; a += m_color[i].a; } - return Color32((unsigned char)(r / 16), (unsigned char)(g / 16), (unsigned char)(b / 16), (unsigned char)(a / 16)); + return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16)); +} + +/// Return true if the block is not fully opaque. +bool ColorBlock::hasAlpha() const +{ + for (uint i = 0; i < 16; i++) + { + if (m_color[i].a != 255) return true; + } + return false; } @@ -170,11 +180,11 @@ Color32 ColorBlock::averageColor() const void ColorBlock::diameterRange(Color32 * start, Color32 * end) const { Color32 c0, c1; - unsigned int best_dist = 0; + uint best_dist = 0; for(int i = 0; i < 16; i++) { for (int j = i+1; j < 16; j++) { - unsigned int dist = colorDistance(m_color[i], m_color[j]); + uint dist = colorDistance(m_color[i], m_color[j]); if( dist > best_dist ) { best_dist = dist; c0 = m_color[i]; @@ -191,13 +201,13 @@ void ColorBlock::diameterRange(Color32 * start, Color32 * end) const void ColorBlock::luminanceRange(Color32 * start, Color32 * end) const { Color32 minColor, maxColor; - unsigned int minLuminance, maxLuminance; + uint minLuminance, maxLuminance; maxLuminance = minLuminance = colorLuminance(m_color[0]); - for(unsigned int i = 1; i < 16; i++) + for(uint i = 1; i < 16; i++) { - unsigned int luminance = colorLuminance(m_color[i]); + uint luminance = colorLuminance(m_color[i]); if (luminance > maxLuminance) { maxLuminance = luminance; @@ -219,7 +229,7 @@ void ColorBlock::boundsRange(Color32 * start, Color32 * end) const Color32 minColor(255, 255, 255); Color32 maxColor(0, 0, 0); - for(unsigned int i = 0; i < 16; i++) + for(uint i = 0; i < 16; i++) { if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; } if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; } @@ -253,7 +263,7 @@ void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const Color32 minColor(255, 255, 255, 255); Color32 maxColor(0, 0, 0, 0); - for(unsigned int i = 0; i < 16; i++) + for(uint i = 0; i < 16; i++) { if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; } if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; } @@ -290,11 +300,11 @@ void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const void ColorBlock::sortColorsByAbsoluteValue() { // Dummy selection sort. - for( unsigned int a = 0; a < 16; a++ ) { - unsigned int max = a; + for( uint a = 0; a < 16; a++ ) { + uint max = a; Color16 cmax(m_color[a]); - for( unsigned int b = a+1; b < 16; b++ ) { + for( uint b = a+1; b < 16; b++ ) { Color16 cb(m_color[b]); if( cb.u > cmax.u ) { @@ -302,9 +312,6 @@ void ColorBlock::sortColorsByAbsoluteValue() cmax = cb; } } - Color32 tmp; - swap( m_color[a], m_color[max], tmp ); + swap( m_color[a], m_color[max] ); } } - - diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index eba372768ad..72049be5f3c 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -45,16 +45,17 @@ struct ColorBlock { ColorBlock(); ColorBlock(const ColorBlock & block); - ColorBlock(const Image * img, unsigned int x, unsigned int y); + ColorBlock(const Image * img, uint x, uint y); - void init(const Image * img, unsigned int x, unsigned int y); + void init(const Image * img, uint x, uint y); void swizzleDXT5n(); void splatX(); void splatY(); - unsigned int countUniqueColors() const; + uint countUniqueColors() const; Color32 averageColor() const; + bool hasAlpha() const; void diameterRange(Color32 * start, Color32 * end) const; void luminanceRange(Color32 * start, Color32 * end) const; @@ -69,11 +70,11 @@ struct ColorBlock // Accessors const Color32 * colors() const; - Color32 color(unsigned int i) const; - Color32 & color(unsigned int i); + Color32 color(uint i) const; + Color32 & color(uint i); - Color32 color(unsigned int x, unsigned int y) const; - Color32 & color(unsigned int x, unsigned int y); + Color32 color(uint x, uint y) const; + Color32 & color(uint x, uint y); private: @@ -89,25 +90,25 @@ inline const Color32 * ColorBlock::colors() const } /// Get block color. -inline Color32 ColorBlock::color(unsigned int i) const +inline Color32 ColorBlock::color(uint i) const { return m_color[i]; } /// Get block color. -inline Color32 & ColorBlock::color(unsigned int i) +inline Color32 & ColorBlock::color(uint i) { return m_color[i]; } /// Get block color. -inline Color32 ColorBlock::color(unsigned int x, unsigned int y) const +inline Color32 ColorBlock::color(uint x, uint y) const { return m_color[y * 4 + x]; } /// Get block color. -inline Color32 & ColorBlock::color(unsigned int x, unsigned int y) +inline Color32 & ColorBlock::color(uint x, uint y) { return m_color[y * 4 + x]; } diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h index 5aa8972e437..0c687e2ca9a 100644 --- a/source/blender/imbuf/intern/dds/Common.h +++ b/source/blender/imbuf/intern/dds/Common.h @@ -37,8 +37,20 @@ #ifndef clamp #define clamp(x,a,b) min(max((x), (a)), (b)) #endif -#ifndef swap -#define swap(a,b,tmp) tmp=a; a=b; b=tmp; -#endif + +template +inline void +swap(T & a, T & b) +{ + T tmp = a; + a = b; + b = tmp; +} + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; +typedef unsigned int uint32; +typedef unsigned long long uint64; #endif diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp index c28f8b5b72d..dafe58a40a7 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp @@ -55,9 +55,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include #include #include +#include #include // printf #include // sqrt @@ -66,92 +66,220 @@ #if !defined(MAKEFOURCC) # define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((unsigned int)((unsigned char)(ch0)) | \ - ((unsigned int)((unsigned char)(ch1)) << 8) | \ - ((unsigned int)((unsigned char)(ch2)) << 16) | \ - ((unsigned int)((unsigned char)(ch3)) << 24 )) + ((uint)((unsigned char)(ch0)) | \ + ((uint)((unsigned char)(ch1)) << 8) | \ + ((uint)((unsigned char)(ch2)) << 16) | \ + ((uint)((unsigned char)(ch3)) << 24 )) #endif -static const unsigned int FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); -static const unsigned int FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); -static const unsigned int FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); -static const unsigned int FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); -static const unsigned int FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); -static const unsigned int FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); -static const unsigned int FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); -static const unsigned int FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); -static const unsigned int FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); +static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); +static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); +static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); +static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); +static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); +static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); +static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); +static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'); +static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); -// RGB formats. -static const unsigned int D3DFMT_R8G8B8 = 20; -static const unsigned int D3DFMT_A8R8G8B8 = 21; -static const unsigned int D3DFMT_X8R8G8B8 = 22; -static const unsigned int D3DFMT_R5G6B5 = 23; -static const unsigned int D3DFMT_X1R5G5B5 = 24; -static const unsigned int D3DFMT_A1R5G5B5 = 25; -static const unsigned int D3DFMT_A4R4G4B4 = 26; -static const unsigned int D3DFMT_R3G3B2 = 27; -static const unsigned int D3DFMT_A8 = 28; -static const unsigned int D3DFMT_A8R3G3B2 = 29; -static const unsigned int D3DFMT_X4R4G4B4 = 30; -static const unsigned int D3DFMT_A2B10G10R10 = 31; -static const unsigned int D3DFMT_A8B8G8R8 = 32; -static const unsigned int D3DFMT_X8B8G8R8 = 33; -static const unsigned int D3DFMT_G16R16 = 34; -static const unsigned int D3DFMT_A2R10G10B10 = 35; -static const unsigned int D3DFMT_A16B16G16R16 = 36; +// 32 bit RGB formats. +static const uint D3DFMT_R8G8B8 = 20; +static const uint D3DFMT_A8R8G8B8 = 21; +static const uint D3DFMT_X8R8G8B8 = 22; +static const uint D3DFMT_R5G6B5 = 23; +static const uint D3DFMT_X1R5G5B5 = 24; +static const uint D3DFMT_A1R5G5B5 = 25; +static const uint D3DFMT_A4R4G4B4 = 26; +static const uint D3DFMT_R3G3B2 = 27; +static const uint D3DFMT_A8 = 28; +static const uint D3DFMT_A8R3G3B2 = 29; +static const uint D3DFMT_X4R4G4B4 = 30; +static const uint D3DFMT_A2B10G10R10 = 31; +static const uint D3DFMT_A8B8G8R8 = 32; +static const uint D3DFMT_X8B8G8R8 = 33; +static const uint D3DFMT_G16R16 = 34; +static const uint D3DFMT_A2R10G10B10 = 35; + +static const uint D3DFMT_A16B16G16R16 = 36; // Palette formats. -static const unsigned int D3DFMT_A8P8 = 40; -static const unsigned int D3DFMT_P8 = 41; +static const uint D3DFMT_A8P8 = 40; +static const uint D3DFMT_P8 = 41; // Luminance formats. -static const unsigned int D3DFMT_L8 = 50; -static const unsigned int D3DFMT_A8L8 = 51; -static const unsigned int D3DFMT_A4L4 = 52; +static const uint D3DFMT_L8 = 50; +static const uint D3DFMT_A8L8 = 51; +static const uint D3DFMT_A4L4 = 52; +static const uint D3DFMT_L16 = 81; // Floating point formats -static const unsigned int D3DFMT_R16F = 111; -static const unsigned int D3DFMT_G16R16F = 112; -static const unsigned int D3DFMT_A16B16G16R16F = 113; -static const unsigned int D3DFMT_R32F = 114; -static const unsigned int D3DFMT_G32R32F = 115; -static const unsigned int D3DFMT_A32B32G32R32F = 116; +static const uint D3DFMT_R16F = 111; +static const uint D3DFMT_G16R16F = 112; +static const uint D3DFMT_A16B16G16R16F = 113; +static const uint D3DFMT_R32F = 114; +static const uint D3DFMT_G32R32F = 115; +static const uint D3DFMT_A32B32G32R32F = 116; -static const unsigned int DDSD_CAPS = 0x00000001U; -static const unsigned int DDSD_PIXELFORMAT = 0x00001000U; -static const unsigned int DDSD_WIDTH = 0x00000004U; -static const unsigned int DDSD_HEIGHT = 0x00000002U; -static const unsigned int DDSD_PITCH = 0x00000008U; -static const unsigned int DDSD_MIPMAPCOUNT = 0x00020000U; -static const unsigned int DDSD_LINEARSIZE = 0x00080000U; -static const unsigned int DDSD_DEPTH = 0x00800000U; +static const uint DDSD_CAPS = 0x00000001U; +static const uint DDSD_PIXELFORMAT = 0x00001000U; +static const uint DDSD_WIDTH = 0x00000004U; +static const uint DDSD_HEIGHT = 0x00000002U; +static const uint DDSD_PITCH = 0x00000008U; +static const uint DDSD_MIPMAPCOUNT = 0x00020000U; +static const uint DDSD_LINEARSIZE = 0x00080000U; +static const uint DDSD_DEPTH = 0x00800000U; -static const unsigned int DDSCAPS_COMPLEX = 0x00000008U; -static const unsigned int DDSCAPS_TEXTURE = 0x00001000U; -static const unsigned int DDSCAPS_MIPMAP = 0x00400000U; -static const unsigned int DDSCAPS2_VOLUME = 0x00200000U; -static const unsigned int DDSCAPS2_CUBEMAP = 0x00000200U; +static const uint DDSCAPS_COMPLEX = 0x00000008U; +static const uint DDSCAPS_TEXTURE = 0x00001000U; +static const uint DDSCAPS_MIPMAP = 0x00400000U; +static const uint DDSCAPS2_VOLUME = 0x00200000U; +static const uint DDSCAPS2_CUBEMAP = 0x00000200U; -static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U; -static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U; -static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U; -static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U; -static const unsigned int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U; -static const unsigned int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U; -static const unsigned int DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U; +static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U; +static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U; +static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U; +static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U; +static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U; +static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U; +static const uint DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U; -static const unsigned int DDPF_ALPHAPIXELS = 0x00000001U; -static const unsigned int DDPF_ALPHA = 0x00000002U; -static const unsigned int DDPF_FOURCC = 0x00000004U; -static const unsigned int DDPF_RGB = 0x00000040U; -static const unsigned int DDPF_PALETTEINDEXED1 = 0x00000800U; -static const unsigned int DDPF_PALETTEINDEXED2 = 0x00001000U; -static const unsigned int DDPF_PALETTEINDEXED4 = 0x00000008U; -static const unsigned int DDPF_PALETTEINDEXED8 = 0x00000020U; -static const unsigned int DDPF_LUMINANCE = 0x00020000U; -static const unsigned int DDPF_ALPHAPREMULT = 0x00008000U; -static const unsigned int DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag. +static const uint DDPF_ALPHAPIXELS = 0x00000001U; +static const uint DDPF_ALPHA = 0x00000002U; +static const uint DDPF_FOURCC = 0x00000004U; +static const uint DDPF_RGB = 0x00000040U; +static const uint DDPF_PALETTEINDEXED1 = 0x00000800U; +static const uint DDPF_PALETTEINDEXED2 = 0x00001000U; +static const uint DDPF_PALETTEINDEXED4 = 0x00000008U; +static const uint DDPF_PALETTEINDEXED8 = 0x00000020U; +static const uint DDPF_LUMINANCE = 0x00020000U; +static const uint DDPF_ALPHAPREMULT = 0x00008000U; +static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag. + + // DX10 formats. + enum DXGI_FORMAT + { + DXGI_FORMAT_UNKNOWN = 0, + + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + + DXGI_FORMAT_R11G11B10_FLOAT = 26, + + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + + DXGI_FORMAT_R1_UNORM = 66, + + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + }; + + enum D3D10_RESOURCE_DIMENSION + { + D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D10_RESOURCE_DIMENSION_BUFFER = 1, + D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4, + }; /*** implementation ***/ @@ -175,6 +303,15 @@ void mem_read(Stream & mem, DDSCaps & caps) mem_read(mem, caps.caps4); } +void mem_read(Stream & mem, DDSHeader10 & header) +{ + mem_read(mem, header.dxgiFormat); + mem_read(mem, header.resourceDimension); + mem_read(mem, header.miscFlag); + mem_read(mem, header.arraySize); + mem_read(mem, header.reserved); +} + void mem_read(Stream & mem, DDSHeader & header) { mem_read(mem, header.fourcc); @@ -185,12 +322,19 @@ void mem_read(Stream & mem, DDSHeader & header) mem_read(mem, header.pitch); mem_read(mem, header.depth); mem_read(mem, header.mipmapcount); - for (unsigned int i = 0; i < 11; i++) mem_read(mem, header.reserved[i]); + for (uint i = 0; i < 11; i++) mem_read(mem, header.reserved[i]); mem_read(mem, header.pf); mem_read(mem, header.caps); mem_read(mem, header.notused); + + if (header.hasDX10Header()) + { + mem_read(mem, header.header10); + } } + + DDSHeader::DDSHeader() { this->fourcc = FOURCC_DDS; @@ -201,11 +345,11 @@ DDSHeader::DDSHeader() this->pitch = 0; this->depth = 0; this->mipmapcount = 0; - for (unsigned int i = 0; i < 11; i++) this->reserved[i] = 0; + for (uint i = 0; i < 11; i++) this->reserved[i] = 0; // Store version information on the reserved header attributes. this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T'); - this->reserved[10] = (0 << 16) | (9 << 8) | (3); // major.minor.revision + this->reserved[10] = (0 << 16) | (9 << 8) | (5); // major.minor.revision this->pf.size = 32; this->pf.flags = 0; @@ -220,29 +364,35 @@ DDSHeader::DDSHeader() this->caps.caps3 = 0; this->caps.caps4 = 0; this->notused = 0; + + this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN; + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; + this->header10.miscFlag = 0; + this->header10.arraySize = 0; + this->header10.reserved = 0; } -void DDSHeader::setWidth(unsigned int w) +void DDSHeader::setWidth(uint w) { this->flags |= DDSD_WIDTH; this->width = w; } -void DDSHeader::setHeight(unsigned int h) +void DDSHeader::setHeight(uint h) { this->flags |= DDSD_HEIGHT; this->height = h; } -void DDSHeader::setDepth(unsigned int d) +void DDSHeader::setDepth(uint d) { this->flags |= DDSD_DEPTH; this->height = d; } -void DDSHeader::setMipmapCount(unsigned int count) +void DDSHeader::setMipmapCount(uint count) { - if (count == 0) + if (count == 0 || count == 1) { this->flags &= ~DDSD_MIPMAPCOUNT; this->mipmapcount = 0; @@ -265,35 +415,40 @@ void DDSHeader::setMipmapCount(unsigned int count) void DDSHeader::setTexture2D() { - // nothing to do here. + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; } void DDSHeader::setTexture3D() { this->caps.caps2 = DDSCAPS2_VOLUME; + + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; } void DDSHeader::setTextureCube() { this->caps.caps1 |= DDSCAPS_COMPLEX; this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES; + + this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + this->header10.arraySize = 6; } -void DDSHeader::setLinearSize(unsigned int size) +void DDSHeader::setLinearSize(uint size) { this->flags &= ~DDSD_PITCH; this->flags |= DDSD_LINEARSIZE; this->pitch = size; } -void DDSHeader::setPitch(unsigned int pitch) +void DDSHeader::setPitch(uint pitch) { this->flags &= ~DDSD_LINEARSIZE; this->flags |= DDSD_PITCH; this->pitch = pitch; } -void DDSHeader::setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3) +void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3) { // set fourcc pixel format. this->pf.flags = DDPF_FOURCC; @@ -305,7 +460,7 @@ void DDSHeader::setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, this->pf.amask = 0; } -void DDSHeader::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask) +void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) { // Make sure the masks are correct. if ((rmask & gmask) || \ @@ -327,15 +482,25 @@ void DDSHeader::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsign if (bitcount == 0) { // Compute bit count from the masks. - unsigned int total = rmask | gmask | bmask | amask; + uint total = rmask | gmask | bmask | amask; while(total != 0) { bitcount++; total >>= 1; } - // @@ Align to 8? } - this->pf.fourcc = 0; + if (!(bitcount > 0 && bitcount <= 32)) { + printf("DDS: bad bit count, pixel format not set\n"); + return; + } + + // Align to 8. + if (bitcount < 8) bitcount = 8; + else if (bitcount < 16) bitcount = 16; + else if (bitcount < 24) bitcount = 24; + else bitcount = 32; + + this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask); this->pf.bitcount = bitcount; this->pf.rmask = rmask; this->pf.gmask = gmask; @@ -343,46 +508,24 @@ void DDSHeader::setPixelFormat(unsigned int bitcount, unsigned int rmask, unsign this->pf.amask = amask; } +void DDSHeader::setDX10Format(uint format) +{ + this->pf.flags = 0; + this->header10.dxgiFormat = format; +} + void DDSHeader::setNormalFlag(bool b) { if (b) this->pf.flags |= DDPF_NORMAL; else this->pf.flags &= ~DDPF_NORMAL; } -/* -void DDSHeader::swapBytes() +bool DDSHeader::hasDX10Header() const { - this->fourcc = POSH_LittleU32(this->fourcc); - this->size = POSH_LittleU32(this->size); - this->flags = POSH_LittleU32(this->flags); - this->height = POSH_LittleU32(this->height); - this->width = POSH_LittleU32(this->width); - this->pitch = POSH_LittleU32(this->pitch); - this->depth = POSH_LittleU32(this->depth); - this->mipmapcount = POSH_LittleU32(this->mipmapcount); - - for(int i = 0; i < 11; i++) { - this->reserved[i] = POSH_LittleU32(this->reserved[i]); - } - - this->pf.size = POSH_LittleU32(this->pf.size); - this->pf.flags = POSH_LittleU32(this->pf.flags); - this->pf.fourcc = POSH_LittleU32(this->pf.fourcc); - this->pf.bitcount = POSH_LittleU32(this->pf.bitcount); - this->pf.rmask = POSH_LittleU32(this->pf.rmask); - this->pf.gmask = POSH_LittleU32(this->pf.gmask); - this->pf.bmask = POSH_LittleU32(this->pf.bmask); - this->pf.amask = POSH_LittleU32(this->pf.amask); - this->caps.caps1 = POSH_LittleU32(this->caps.caps1); - this->caps.caps2 = POSH_LittleU32(this->caps.caps2); - this->caps.caps3 = POSH_LittleU32(this->caps.caps3); - this->caps.caps4 = POSH_LittleU32(this->caps.caps4); - this->notused = POSH_LittleU32(this->notused); + return this->pf.flags == 0; } -*/ - -DirectDrawSurface::DirectDrawSurface(unsigned char *mem, unsigned int size) : stream(mem, size), header() +DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header() { mem_read(stream, header); } @@ -398,7 +541,7 @@ bool DirectDrawSurface::isValid() const return false; } - const unsigned int required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); + const uint required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); if( (header.flags & required) != required ) { return false; } @@ -436,19 +579,7 @@ bool DirectDrawSurface::isSupported() const } else if (header.pf.flags & DDPF_RGB) { - if (header.pf.bitcount == 24) - { - return true; - } - else if (header.pf.bitcount == 32) - { - return true; - } - else - { - // Unsupported pixel format. - return false; - } + // All RGB formats are supported now. } else { @@ -471,26 +602,26 @@ bool DirectDrawSurface::isSupported() const } -unsigned int DirectDrawSurface::mipmapCount() const +uint DirectDrawSurface::mipmapCount() const { if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount; else return 0; } -unsigned int DirectDrawSurface::width() const +uint DirectDrawSurface::width() const { if (header.flags & DDSD_WIDTH) return header.width; else return 1; } -unsigned int DirectDrawSurface::height() const +uint DirectDrawSurface::height() const { if (header.flags & DDSD_HEIGHT) return header.height; else return 1; } -unsigned int DirectDrawSurface::depth() const +uint DirectDrawSurface::depth() const { if (header.flags & DDSD_DEPTH) return header.depth; else return 1; @@ -527,18 +658,18 @@ bool DirectDrawSurface::isTextureCube() const return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0; } -void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipmap) +void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap) { stream.seek(offset(face, mipmap)); - unsigned int w = width(); - unsigned int h = height(); + uint w = width(); + uint h = height(); // Compute width and height. - for (unsigned int m = 0; m < mipmap; m++) + for (uint m = 0; m < mipmap; m++) { - w = max(w/2, 1U); - h = max(h/2, 1U); + w = max(1U, w / 2); + h = max(1U, h / 2); } img->allocate(w, h); @@ -553,73 +684,30 @@ void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipm } } -/* helper function for readLinearImage */ -void maskShiftAndSize(unsigned int mask, unsigned int * shift, unsigned int * size) -{ - if (!mask) - { - *shift = 0; - *size = 0; - return; - } - - *shift = 0; - while((mask & 1) == 0) { - ++(*shift); - mask >>= 1; - } - - *size = 0; - while((mask & 1) == 1) { - ++(*size); - mask >>= 1; - } -} - -/* helper function for readLinearImage */ -unsigned int convert(unsigned int c, unsigned int inbits, unsigned int outbits) -{ - if (inbits == 0) { - return 0; - } - else if (inbits == outbits) - { - return c; - } - else if (inbits > outbits) - { - // truncate - return c >> (inbits - outbits); - } - else - { - // bitexpand - return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); - } -} - void DirectDrawSurface::readLinearImage(Image * img) { - const unsigned int w = img->width(); - const unsigned int h = img->height(); + + const uint w = img->width(); + const uint h = img->height(); + + uint rshift, rsize; + PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize); + + uint gshift, gsize; + PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize); + + uint bshift, bsize; + PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize); + + uint ashift, asize; + PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize); - unsigned int rshift, rsize; - maskShiftAndSize(header.pf.rmask, &rshift, &rsize); - - unsigned int gshift, gsize; - maskShiftAndSize(header.pf.gmask, &gshift, &gsize); - - unsigned int bshift, bsize; - maskShiftAndSize(header.pf.bmask, &bshift, &bsize); - - unsigned int ashift, asize; - maskShiftAndSize(header.pf.amask, &ashift, &asize); + uint byteCount = (header.pf.bitcount + 7) / 8; - unsigned int byteCount = (header.pf.bitcount + 7) / 8; if (byteCount > 4) { /* just in case... we could have segfaults later on if byteCount > 4 */ - printf("DDS: bitcount too large (file corrupt?)"); + printf("DDS: bitcount too large"); return; } @@ -629,18 +717,18 @@ void DirectDrawSurface::readLinearImage(Image * img) } // Read linear RGB images. - for (unsigned int y = 0; y < h; y++) + for (uint y = 0; y < h; y++) { - for (unsigned int x = 0; x < w; x++) + for (uint x = 0; x < w; x++) { - unsigned int c = 0; + uint c = 0; mem_read(stream, (unsigned char *)(&c), byteCount); Color32 pixel(0, 0, 0, 0xFF); - pixel.r = convert(c >> rshift, rsize, 8); - pixel.g = convert(c >> gshift, gsize, 8); - pixel.b = convert(c >> bshift, bsize, 8); - pixel.a = convert(c >> ashift, asize, 8); + pixel.r = PixelFormat::convert(c >> rshift, rsize, 8); + pixel.g = PixelFormat::convert(c >> gshift, gsize, 8); + pixel.b = PixelFormat::convert(c >> bshift, bsize, 8); + pixel.a = PixelFormat::convert(c >> ashift, asize, 8); img->pixel(x, y) = pixel; } @@ -649,15 +737,15 @@ void DirectDrawSurface::readLinearImage(Image * img) void DirectDrawSurface::readBlockImage(Image * img) { - const unsigned int w = img->width(); - const unsigned int h = img->height(); + const uint w = img->width(); + const uint h = img->height(); - const unsigned int bw = (w + 3) / 4; - const unsigned int bh = (h + 3) / 4; + const uint bw = (w + 3) / 4; + const uint bh = (h + 3) / 4; - for (unsigned int by = 0; by < bh; by++) + for (uint by = 0; by < bh; by++) { - for (unsigned int bx = 0; bx < bw; bx++) + for (uint bx = 0; bx < bw; bx++) { ColorBlock block; @@ -665,9 +753,9 @@ void DirectDrawSurface::readBlockImage(Image * img) readBlock(&block); // Write color block. - for (unsigned int y = 0; y < min(4U, h-4*by); y++) + for (uint y = 0; y < min(4U, h-4*by); y++) { - for (unsigned int x = 0; x < min(4U, w-4*bx); x++) + for (uint x = 0; x < min(4U, w-4*bx); x++) { img->pixel(4*bx+x, 4*by+y) = block.color(x, y); } @@ -676,12 +764,13 @@ void DirectDrawSurface::readBlockImage(Image * img) } } -static Color32 buildNormal(unsigned char x, unsigned char y) +static Color32 buildNormal(uint8 x, uint8 y) { - float nx = 2 * (x / 255) - 1; - float ny = 2 * (x / 255) - 1; - float nz = sqrt(1 - nx*nx - ny*ny); - unsigned char z = clamp(int(255 * (nz + 1) / 2), 0, 255); + float nx = 2 * (x / 255.0f) - 1; + float ny = 2 * (y / 255.0f) - 1; + float nz = 0.0f; + if (1 - nx*nx - ny*ny > 0) nz = sqrtf(1 - nx*nx - ny*ny); + uint8 z = clamp(int(255.0f * (nz + 1) / 2.0f), 0, 255); return Color32(x, y, z); } @@ -716,7 +805,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba) for (int i = 0; i < 16; i++) { Color32 & c = rgba->color(i); - unsigned int tmp = c.r; + uint tmp = c.r; c.r = c.a; c.a = tmp; } @@ -751,14 +840,14 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba) for (int i = 0; i < 16; i++) { Color32 & c = rgba->color(i); - c = buildNormal(c.g, c.a); + c = buildNormal(c.a, c.g); } } } } -unsigned int DirectDrawSurface::blockSize() const +uint DirectDrawSurface::blockSize() const { switch(header.pf.fourcc) { @@ -778,13 +867,13 @@ unsigned int DirectDrawSurface::blockSize() const return 0; } -unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const +uint DirectDrawSurface::mipmapSize(uint mipmap) const { - unsigned int w = width(); - unsigned int h = height(); - unsigned int d = depth(); + uint w = width(); + uint h = height(); + uint d = depth(); - for (unsigned int m = 0; m < mipmap; m++) + for (uint m = 0; m < mipmap; m++) { w = max(1U, w / 2); h = max(1U, h / 2); @@ -801,10 +890,10 @@ unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const else if (header.pf.flags & DDPF_RGB) { // Align pixels to bytes. - unsigned int byteCount = (header.pf.bitcount + 7) / 8; + uint byteCount = (header.pf.bitcount + 7) / 8; // Align pitch to 4 bytes. - unsigned int pitch = 4 * ((w * byteCount + 3) / 4); + uint pitch = 4 * ((w * byteCount + 3) / 4); return pitch * h * d; } @@ -814,12 +903,12 @@ unsigned int DirectDrawSurface::mipmapSize(unsigned int mipmap) const }; } -unsigned int DirectDrawSurface::faceSize() const +uint DirectDrawSurface::faceSize() const { - const unsigned int count = mipmapCount(); - unsigned int size = 0; + const uint count = mipmapCount(); + uint size = 0; - for (unsigned int m = 0; m < count; m++) + for (uint m = 0; m < count; m++) { size += mipmapSize(m); } @@ -827,16 +916,16 @@ unsigned int DirectDrawSurface::faceSize() const return size; } -unsigned int DirectDrawSurface::offset(const unsigned int face, const unsigned int mipmap) +uint DirectDrawSurface::offset(const uint face, const uint mipmap) { - unsigned int size = sizeof(DDSHeader); + uint size = 128; //sizeof(DDSHeader); if (face != 0) { size += face * faceSize(); } - for (unsigned int m = 0; m < mipmap; m++) + for (uint m = 0; m < mipmap; m++) { size += mipmapSize(m); } @@ -911,6 +1000,15 @@ void DirectDrawSurface::printInfo() const printf("\tCaps 3: 0x%.8X\n", header.caps.caps3); printf("\tCaps 4: 0x%.8X\n", header.caps.caps4); + if (header.pf.flags == 0) + { + printf("DX10 Header:\n"); + printf("\tDXGI Format: %u\n", header.header10.dxgiFormat); + printf("\tResource dimension: %u\n", header.header10.resourceDimension); + printf("\tMisc flag: %u\n", header.header10.miscFlag); + printf("\tArray size: %u\n", header.header10.arraySize); + } + if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T')) { int major = (header.reserved[10] >> 16) & 0xFF; diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index 2b3319d05a1..d29d82f53f9 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -58,92 +58,110 @@ #ifndef _DDS_DIRECTDRAWSURFACE_H #define _DDS_DIRECTDRAWSURFACE_H +#include #include #include #include -struct DDSPixelFormat { - unsigned int size; - unsigned int flags; - unsigned int fourcc; - unsigned int bitcount; - unsigned int rmask; - unsigned int gmask; - unsigned int bmask; - unsigned int amask; +struct DDSPixelFormat +{ + uint size; + uint flags; + uint fourcc; + uint bitcount; + uint rmask; + uint gmask; + uint bmask; + uint amask; }; -struct DDSCaps { - unsigned int caps1; - unsigned int caps2; - unsigned int caps3; - unsigned int caps4; +struct DDSCaps +{ + uint caps1; + uint caps2; + uint caps3; + uint caps4; +}; + +/// DDS file header for DX10. +struct DDSHeader10 +{ + uint dxgiFormat; + uint resourceDimension; + uint miscFlag; + uint arraySize; + uint reserved; }; /// DDS file header. -struct DDSHeader { - unsigned int fourcc; - unsigned int size; - unsigned int flags; - unsigned int height; - unsigned int width; - unsigned int pitch; - unsigned int depth; - unsigned int mipmapcount; - unsigned int reserved[11]; +struct DDSHeader +{ + uint fourcc; + uint size; + uint flags; + uint height; + uint width; + uint pitch; + uint depth; + uint mipmapcount; + uint reserved[11]; DDSPixelFormat pf; DDSCaps caps; - unsigned int notused; - + uint notused; + DDSHeader10 header10; + + // Helper methods. DDSHeader(); - void setWidth(unsigned int w); - void setHeight(unsigned int h); - void setDepth(unsigned int d); - void setMipmapCount(unsigned int count); + void setWidth(uint w); + void setHeight(uint h); + void setDepth(uint d); + void setMipmapCount(uint count); void setTexture2D(); void setTexture3D(); void setTextureCube(); - void setLinearSize(unsigned int size); - void setPitch(unsigned int pitch); - void setFourCC(unsigned char c0, unsigned char c1, unsigned char c2, unsigned char c3); - void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); + void setLinearSize(uint size); + void setPitch(uint pitch); + void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3); + void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask); + void setDX10Format(uint format); void setNormalFlag(bool b); - /* void swapBytes(); */ + bool hasDX10Header() const; }; /// DirectDraw Surface. (DDS) class DirectDrawSurface { public: - DirectDrawSurface(unsigned char *mem, unsigned int size); + DirectDrawSurface(unsigned char *mem, uint size); ~DirectDrawSurface(); bool isValid() const; bool isSupported() const; - unsigned int mipmapCount() const; - unsigned int width() const; - unsigned int height() const; - unsigned int depth() const; + uint mipmapCount() const; + uint width() const; + uint height() const; + uint depth() const; bool isTexture2D() const; bool isTexture3D() const; bool isTextureCube() const; - bool hasAlpha() const; /* false for DXT1, true for all others */ + bool hasAlpha() const; /* false for DXT1, true for all other DXTs */ - void mipmap(Image * img, unsigned int f, unsigned int m); + void mipmap(Image * img, uint f, uint m); + // void mipmap(FloatImage * img, uint f, uint m); void printInfo() const; private: - unsigned int blockSize() const; - unsigned int faceSize() const; - unsigned int mipmapSize(unsigned int m) const; + uint blockSize() const; + uint faceSize() const; + uint mipmapSize(uint m) const; - unsigned int offset(unsigned int f, unsigned int m); + uint offset(uint f, uint m); void readLinearImage(Image * img); void readBlockImage(Image * img); @@ -158,5 +176,6 @@ private: void mem_read(Stream & mem, DDSPixelFormat & pf); void mem_read(Stream & mem, DDSCaps & caps); void mem_read(Stream & mem, DDSHeader & header); +void mem_read(Stream & mem, DDSHeader10 & header); #endif // _DDS_DIRECTDRAWSURFACE_H diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp index f3e6fa38955..d8be7857c3f 100644 --- a/source/blender/imbuf/intern/dds/Image.cpp +++ b/source/blender/imbuf/intern/dds/Image.cpp @@ -48,7 +48,7 @@ Image::~Image() free(); } -void Image::allocate(unsigned int w, unsigned int h) +void Image::allocate(uint w, uint h) { free(); m_width = w; @@ -63,17 +63,17 @@ void Image::free() } -unsigned int Image::width() const +uint Image::width() const { return m_width; } -unsigned int Image::height() const +uint Image::height() const { return m_height; } -const Color32 * Image::scanline(unsigned int h) const +const Color32 * Image::scanline(uint h) const { if (h >= m_height) { printf("DDS: scanline beyond dimensions of image"); @@ -82,7 +82,7 @@ const Color32 * Image::scanline(unsigned int h) const return m_data + h * m_width; } -Color32 * Image::scanline(unsigned int h) +Color32 * Image::scanline(uint h) { if (h >= m_height) { printf("DDS: scanline beyond dimensions of image"); @@ -101,7 +101,7 @@ Color32 * Image::pixels() return m_data; } -const Color32 & Image::pixel(unsigned int idx) const +const Color32 & Image::pixel(uint idx) const { if (idx >= m_width * m_height) { printf("DDS: pixel beyond dimensions of image"); @@ -110,7 +110,7 @@ const Color32 & Image::pixel(unsigned int idx) const return m_data[idx]; } -Color32 & Image::pixel(unsigned int idx) +Color32 & Image::pixel(uint idx) { if (idx >= m_width * m_height) { printf("DDS: pixel beyond dimensions of image"); diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index 10356774777..0241839d01d 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -37,6 +37,7 @@ #ifndef _DDS_IMAGE_H #define _DDS_IMAGE_H +#include #include /// 32 bit RGBA image. @@ -53,28 +54,28 @@ public: Image(); ~Image(); - void allocate(unsigned int w, unsigned int h); + void allocate(uint w, uint h); /* bool load(const char * name); - void wrap(void * data, unsigned int w, unsigned int h); + void wrap(void * data, uint w, uint h); void unwrap(); */ - unsigned int width() const; - unsigned int height() const; + uint width() const; + uint height() const; - const Color32 * scanline(unsigned int h) const; - Color32 * scanline(unsigned int h); + const Color32 * scanline(uint h) const; + Color32 * scanline(uint h); const Color32 * pixels() const; Color32 * pixels(); - const Color32 & pixel(unsigned int idx) const; - Color32 & pixel(unsigned int idx); + const Color32 & pixel(uint idx) const; + Color32 & pixel(uint idx); - const Color32 & pixel(unsigned int x, unsigned int y) const; - Color32 & pixel(unsigned int x, unsigned int y); + const Color32 & pixel(uint x, uint y) const; + Color32 & pixel(uint x, uint y); Format format() const; void setFormat(Format f); @@ -83,19 +84,19 @@ private: void free(); private: - unsigned int m_width; - unsigned int m_height; + uint m_width; + uint m_height; Format m_format; Color32 * m_data; }; -inline const Color32 & Image::pixel(unsigned int x, unsigned int y) const +inline const Color32 & Image::pixel(uint x, uint y) const { return pixel(y * width() + x); } -inline Color32 & Image::pixel(unsigned int x, unsigned int y) +inline Color32 & Image::pixel(uint x, uint y) { return pixel(y * width() + x); } diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h new file mode 100644 index 00000000000..93f55f8266a --- /dev/null +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -0,0 +1,110 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributors: Amorilia (amorilia@gamebox.net) + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* + * This file is based on a similar file from the NVIDIA texture tools + * (http://nvidia-texture-tools.googlecode.com/) + * + * Original license from NVIDIA follows. + */ + +// Copyright NVIDIA Corporation 2007 -- Ignacio Castano +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#ifndef _DDS_PIXELFORMAT_H +#define _DDS_PIXELFORMAT_H + +#include + + namespace PixelFormat + { + + // Convert component @a c having @a inbits to the returned value having @a outbits. + inline uint convert(uint c, uint inbits, uint outbits) + { + if (inbits == 0) + { + return 0; + } + else if (inbits >= outbits) + { + // truncate + return c >> (inbits - outbits); + } + else + { + // bitexpand + return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits); + } + } + + // Get pixel component shift and size given its mask. + inline void maskShiftAndSize(uint mask, uint * shift, uint * size) + { + if (!mask) + { + *shift = 0; + *size = 0; + return; + } + + *shift = 0; + while((mask & 1) == 0) { + ++(*shift); + mask >>= 1; + } + + *size = 0; + while((mask & 1) == 1) { + ++(*size); + mask >>= 1; + } + } + + } // PixelFormat namespace + +#endif // _DDS_IMAGE_PIXELFORMAT_H From 015007beafeaeec09ba8a7fc859acc40ba6b8b16 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 26 Dec 2007 22:40:56 +0000 Subject: [PATCH 60/99] == Sculpt == Fixed bad level calls in sculptmode. --- .../blender/blenkernel/BKE_bad_level_calls.h | 6 - source/blender/blenkernel/BKE_mesh.h | 5 + source/blender/blenkernel/BKE_multires.h | 2 +- source/blender/blenkernel/BKE_scene.h | 2 + source/blender/blenkernel/BKE_sculpt.h | 64 +++++ .../blenkernel/bad_level_call_stubs/stubs.c | 4 - source/blender/blenkernel/intern/mesh.c | 69 ++++- source/blender/blenkernel/intern/multires.c | 10 +- source/blender/blenkernel/intern/scene.c | 123 +++++++- source/blender/include/BDR_sculptmode.h | 39 +-- source/blender/src/buttons_editing.c | 2 +- source/blender/src/drawview.c | 1 + source/blender/src/editobject.c | 2 +- source/blender/src/multires.c | 2 +- source/blender/src/sculptmode-stroke.c | 5 + source/blender/src/sculptmode.c | 267 +++--------------- source/blender/src/space.c | 3 +- source/blender/src/view.c | 1 + 18 files changed, 318 insertions(+), 289 deletions(-) create mode 100644 source/blender/blenkernel/BKE_sculpt.h diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 923504dfeab..94eafbf9f71 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -207,12 +207,6 @@ void post_layer_create(struct VLayer *vlayer); void post_layer_destroy(struct VLayer *vlayer); void post_server_add(void); -/* sculptmode.c */ -struct SculptData; -void sculpt_reset_curve(struct SculptData *sd); -void sculptmode_free_all(struct Scene *sce); -void sculptmode_init(struct Scene *sce); - /* zbuf.c */ void antialias_tagbuf(int xsize, int ysize, char *rectmove); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index be0a04ba563..b60fd0ce954 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -111,6 +111,11 @@ UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v); void free_uv_vert_map(UvVertMap *vmap); +/* Partial Mesh Visibility */ +struct PartialVisibility *mesh_pmv_copy(struct PartialVisibility *); +void mesh_pmv_free(struct PartialVisibility *); +void mesh_pmv_revert(struct Object *ob, struct Mesh *me); +void mesh_pmv_off(struct Object *ob, struct Mesh *me); /* functions for making menu's from customdata layers */ int mesh_layers_menu_charlen(struct CustomData *data, int type); /* use this to work out how many chars to allocate */ diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 1335f250322..61eb796e53d 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -47,7 +47,7 @@ void multires_edge_level_update(struct Object *ob, struct Mesh *me); void multires_free(struct Multires *mr); struct Multires *multires_copy(struct Multires *orig); -void multires_create(struct Mesh *me); +void multires_create(struct Object *ob, struct Mesh *me); /* CustomData */ void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 69ff6876acd..30953835406 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -34,11 +34,13 @@ #ifndef BKE_SCENE_H #define BKE_SCENE_H +struct bglMats; struct Scene; struct Object; struct Base; struct AviCodecData; struct QuicktimeCodecData; +struct SculptData; /* sequence related defines */ #define WHILE_SEQ(base) { \ diff --git a/source/blender/blenkernel/BKE_sculpt.h b/source/blender/blenkernel/BKE_sculpt.h new file mode 100644 index 00000000000..61b8dc071aa --- /dev/null +++ b/source/blender/blenkernel/BKE_sculpt.h @@ -0,0 +1,64 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 by Nicholas Bishop + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +typedef struct SculptSession { + struct ProjVert *projverts; + + struct bglMats *mats; + + /* An array of lists; array is sized as + large as the number of verts in the mesh, + the list for each vert contains the index + for all the faces that use that vertex */ + struct ListBase *vertex_users; + struct IndexNode *vertex_users_mem; + int vertex_users_size; + + /* Used temporarily per-stroke */ + float *vertexcosnos; + ListBase damaged_rects; + ListBase damaged_verts; + + /* Used to cache the render of the active texture */ + unsigned int texcache_w, texcache_h, *texcache; + + struct PropsetData *propset; + + /* For rotating around a pivot point */ + vec3f pivot; + + struct SculptStroke *stroke; +} SculptSession; + +void sculptdata_init(struct Scene *sce); +void sculptdata_free(struct Scene *sce); +void sculptsession_free(struct Scene *sce); +void sculpt_vertexusers_free(struct SculptSession *ss); +void sculpt_reset_curve(struct SculptData *sd); + diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 8885d4db760..1bcbed1efb1 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -310,10 +310,6 @@ void post_geometry_free_constraint(struct VNode *vnode) {} void post_layer_create(struct VLayer *vlayer) {} void post_layer_destroy(struct VLayer *vlayer) {} void post_server_add(void) {} - /* sculpt stubs */ -void sculpt_reset_curve(struct SculptData *sd) {} -void sculptmode_init(struct Scene *sce) {} -void sculptmode_free_all(struct Scene *sce) {} /* zbuf.c stub */ void antialias_tagbuf(int xsize, int ysize, char *rectmove) {} diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 6156b2bed89..25a391be566 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -55,8 +55,6 @@ #include "DNA_meshdata_types.h" #include "DNA_ipo_types.h" -#include "BDR_sculptmode.h" - #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_main.h" @@ -1230,3 +1228,70 @@ void free_uv_vert_map(UvVertMap *vmap) } } +/* Partial Mesh Visibility */ +PartialVisibility *mesh_pmv_copy(PartialVisibility *pmv) +{ + PartialVisibility *n= MEM_dupallocN(pmv); + n->vert_map= MEM_dupallocN(pmv->vert_map); + n->edge_map= MEM_dupallocN(pmv->edge_map); + n->old_edges= MEM_dupallocN(pmv->old_edges); + n->old_faces= MEM_dupallocN(pmv->old_faces); + return n; +} + +void mesh_pmv_free(PartialVisibility *pv) +{ + MEM_freeN(pv->vert_map); + MEM_freeN(pv->edge_map); + MEM_freeN(pv->old_faces); + MEM_freeN(pv->old_edges); + MEM_freeN(pv); +} + +void mesh_pmv_revert(Object *ob, Mesh *me) +{ + if(me->pv) { + unsigned i; + MVert *nve, *old_verts; + + /* Reorder vertices */ + nve= me->mvert; + old_verts = MEM_mallocN(sizeof(MVert)*me->pv->totvert,"PMV revert verts"); + for(i=0; ipv->totvert; ++i) + old_verts[i]= nve[me->pv->vert_map[i]]; + + /* Restore verts, edges and faces */ + CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); + CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); + CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); + + CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, old_verts, me->pv->totvert); + CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->pv->old_edges, me->pv->totedge); + CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->pv->old_faces, me->pv->totface); + mesh_update_customdata_pointers(me); + + me->totvert= me->pv->totvert; + me->totedge= me->pv->totedge; + me->totface= me->pv->totface; + + me->pv->old_edges= NULL; + me->pv->old_faces= NULL; + + /* Free maps */ + MEM_freeN(me->pv->edge_map); + me->pv->edge_map= NULL; + MEM_freeN(me->pv->vert_map); + me->pv->vert_map= NULL; + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } +} + +void mesh_pmv_off(Object *ob, Mesh *me) +{ + if(ob && me->pv) { + mesh_pmv_revert(ob, me); + MEM_freeN(me->pv); + me->pv= NULL; + } +} diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index c402d59f2c0..0874890a2c6 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -35,8 +35,6 @@ #include "DNA_object_types.h" #include "DNA_vec_types.h" -#include "BDR_sculptmode.h" - #include "BIF_editmesh.h" #include "BLI_arithb.h" @@ -348,7 +346,7 @@ void multires_load_cols(Mesh *me) } } -void multires_create(Mesh *me) +void multires_create(Object *ob, Mesh *me) { MultiresLevel *lvl; EditMesh *em= G.obedit ? G.editMesh : NULL; @@ -359,7 +357,7 @@ void multires_create(Mesh *me) lvl= MEM_callocN(sizeof(MultiresLevel), "multires level"); - if(me->pv) sculptmode_pmv_off(me); + if(me->pv) mesh_pmv_off(ob, me); me->mr= MEM_callocN(sizeof(Multires), "multires data"); @@ -1105,7 +1103,7 @@ void multires_add_level(Object *ob, Mesh *me, const char subdiv_type) MVert *oldverts= NULL; lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel"); - if(me->pv) sculptmode_pmv_off(me); + if(me->pv) mesh_pmv_off(ob, me); check_colors(me); multires_update_levels(me, 0); @@ -1271,7 +1269,7 @@ void multires_add_level(Object *ob, Mesh *me, const char subdiv_type) void multires_set_level(Object *ob, Mesh *me, const int render) { - if(me->pv) sculptmode_pmv_off(me); + if(me->pv) mesh_pmv_off(ob, me); check_colors(me); multires_update_levels(me, render); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index ff7b429845d..88dca65f594 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -47,6 +47,7 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_color_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" @@ -63,6 +64,7 @@ #include "BKE_anim.h" #include "BKE_armature.h" #include "BKE_bad_level_calls.h" +#include "BKE_colortools.h" #include "BKE_constraint.h" #include "BKE_depsgraph.h" #include "BKE_global.h" @@ -75,11 +77,11 @@ #include "BKE_node.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_sculpt.h" #include "BKE_world.h" #include "BKE_utildefines.h" #include "BIF_previewrender.h" -#include "BDR_sculptmode.h" #include "BPY_extern.h" #include "BLI_arithb.h" @@ -168,7 +170,7 @@ void free_scene(Scene *sce) MEM_freeN(sce->nodetree); } - sculptmode_free_all(sce); + sculptdata_free(sce); } Scene *add_scene(char *name) @@ -259,7 +261,7 @@ Scene *add_scene(char *name) BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f); sce->r.osa= 8; - sculptmode_init(sce); + sculptdata_init(sce); /* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */ scene_add_render_layer(sce); @@ -578,3 +580,118 @@ void scene_add_render_layer(Scene *sce) srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z; } +/* Initialize 'permanent' sculpt data that is saved with file kept after + switching out of sculptmode. */ +void sculptdata_init(Scene *sce) +{ + SculptData *sd; + + if(!sce) + return; + + sd= &sce->sculptdata; + + if(sd->cumap) + curvemapping_free(sd->cumap); + + memset(sd, 0, sizeof(SculptData)); + + sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size = + sd->inflatebrush.size = sd->grabbrush.size = + sd->layerbrush.size = sd->flattenbrush.size = 50; + sd->drawbrush.strength = sd->smoothbrush.strength = + sd->pinchbrush.strength = sd->inflatebrush.strength = + sd->grabbrush.strength = sd->layerbrush.strength = + sd->flattenbrush.strength = 25; + sd->drawbrush.dir = sd->pinchbrush.dir = sd->inflatebrush.dir = sd->layerbrush.dir= 1; + sd->drawbrush.airbrush = sd->smoothbrush.airbrush = + sd->pinchbrush.airbrush = sd->inflatebrush.airbrush = + sd->layerbrush.airbrush = sd->flattenbrush.airbrush = 0; + sd->drawbrush.view= 0; + sd->brush_type= DRAW_BRUSH; + sd->texact= -1; + sd->texfade= 1; + sd->averaging= 1; + sd->texsep= 0; + sd->texrept= SCULPTREPT_DRAG; + sd->flags= SCULPT_DRAW_BRUSH; + sd->tablet_size=3; + sd->tablet_strength=10; + sd->rake=0; + sculpt_reset_curve(sd); +} + +void sculptdata_free(Scene *sce) +{ + SculptData *sd= &sce->sculptdata; + int a; + + sculptsession_free(sce); + + for(a=0; amtex[a]; + if(mtex) { + if(mtex->tex) mtex->tex->id.us--; + MEM_freeN(mtex); + } + } + + curvemapping_free(sd->cumap); + sd->cumap = NULL; +} + +void sculpt_vertexusers_free(SculptSession *ss) +{ + if(ss && ss->vertex_users){ + MEM_freeN(ss->vertex_users); + MEM_freeN(ss->vertex_users_mem); + ss->vertex_users= NULL; + ss->vertex_users_mem= NULL; + ss->vertex_users_size= 0; + } +} + +void sculptsession_free(Scene *sce) +{ + SculptSession *ss= sce->sculptdata.session; + if(ss) { + if(ss->projverts) + MEM_freeN(ss->projverts); + if(ss->mats) + MEM_freeN(ss->mats); + sculpt_vertexusers_free(ss); + if(ss->texcache) + MEM_freeN(ss->texcache); + MEM_freeN(ss); + sce->sculptdata.session= NULL; + } +} + +/* Default curve approximates 0.5 * (cos(pi * x) + 1), with 0 <= x <= 1 */ +void sculpt_reset_curve(SculptData *sd) +{ + CurveMap *cm = NULL; + + if(!sd->cumap) + sd->cumap = curvemapping_add(1, 0, 0, 1, 1); + + cm = sd->cumap->cm; + + if(cm->curve) + MEM_freeN(cm->curve); + cm->curve= MEM_callocN(6*sizeof(CurveMapPoint), "curve points"); + cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; + cm->totpoint= 6; + cm->curve[0].x= 0; + cm->curve[0].y= 1; + cm->curve[1].x= 0.1; + cm->curve[1].y= 0.97553; + cm->curve[2].x= 0.3; + cm->curve[2].y= 0.79389; + cm->curve[3].x= 0.9; + cm->curve[3].y= 0.02447; + cm->curve[4].x= 0.7; + cm->curve[4].y= 0.20611; + cm->curve[5].x= 1; + cm->curve[5].y= 0; +} diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h index abbb17ac42b..884f1000b1f 100644 --- a/source/blender/include/BDR_sculptmode.h +++ b/source/blender/include/BDR_sculptmode.h @@ -32,8 +32,6 @@ #include "DNA_listBase.h" #include "DNA_vec_types.h" -/* For bglMats */ -#include "BIF_glutil.h" #include "transform.h" struct uiBlock; @@ -55,6 +53,7 @@ typedef enum PropsetMode { PropsetStrength, PropsetTexRot } PropsetMode; + typedef struct PropsetData { PropsetMode mode; unsigned int tex; @@ -68,40 +67,10 @@ typedef struct PropsetData { NumInput num; } PropsetData; -typedef struct SculptSession { - bglMats mats; - - /* An array of lists; array is sized as - large as the number of verts in the mesh, - the list for each vert contains the index - for all the faces that use that vertex */ - struct ListBase *vertex_users; - struct IndexNode *vertex_users_mem; - int vertex_users_size; - - /* Used temporarily per-stroke */ - float *vertexcosnos; - ListBase damaged_rects; - ListBase damaged_verts; - - /* Used to cache the render of the active texture */ - unsigned int texcache_w, texcache_h, *texcache; - - PropsetData *propset; - - /* For rotating around a pivot point */ - vec3f pivot; - - struct SculptStroke *stroke; -} SculptSession; - -SculptSession *sculpt_session(void); +struct SculptSession *sculpt_session(void); struct SculptData *sculpt_data(void); /* Memory */ -void sculpt_reset_curve(struct SculptData *sd); -void sculptmode_init(struct Scene *); -void sculptmode_free_all(struct Scene *); void sculptmode_correct_state(void); /* Interface */ @@ -135,10 +104,6 @@ void sculpt_stroke_draw(); /* Partial Mesh Visibility */ -struct PartialVisibility *sculptmode_copy_pmv(struct PartialVisibility *); -void sculptmode_pmv_free(struct PartialVisibility *); -void sculptmode_revert_pmv(struct Mesh *me); -void sculptmode_pmv_off(struct Mesh *me); void sculptmode_pmv(int mode); #endif diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 0cc3a70d2d1..e1c60f8f493 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1356,7 +1356,7 @@ static void modifiers_applyModifier(void *obv, void *mdv) return; } - sculptmode_pmv_off(me); + mesh_pmv_off(ob, me); dm = mesh_create_derived_for_modifier(ob, md); if (!dm) { diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 5568cc17231..8580774e9dc 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -108,6 +108,7 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_scene.h" +#include "BKE_sculpt.h" #include "BKE_texture.h" #include "BKE_utildefines.h" diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 163417d9f08..354d99095f8 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -1621,7 +1621,7 @@ void enter_editmode(int wc) if(ob->type==OB_MESH) { me= get_mesh(ob); if( me==0 ) return; - if(me->pv) sculptmode_pmv_off(me); + if(me->pv) mesh_pmv_off(ob, me); ok= 1; G.obedit= ob; make_editMesh(); diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c index 56bfad4e4db..67485529525 100644 --- a/source/blender/src/multires.c +++ b/source/blender/src/multires.c @@ -233,7 +233,7 @@ void multires_make(void *ob, void *me_v) multires_check_state(); - multires_create(me); + multires_create(ob, me); allqueue(REDRAWBUTSEDIT, 0); BIF_undo_push("Make multires"); diff --git a/source/blender/src/sculptmode-stroke.c b/source/blender/src/sculptmode-stroke.c index 2f8dac2818c..c2c96b04a1d 100644 --- a/source/blender/src/sculptmode-stroke.c +++ b/source/blender/src/sculptmode-stroke.c @@ -31,11 +31,16 @@ */ #include "MEM_guardedalloc.h" + #include "DNA_listBase.h" #include "DNA_scene_types.h" + +#include "BKE_sculpt.h" #include "BLI_blenlib.h" #include "BIF_gl.h" + #include "BDR_sculptmode.h" + #include /* Temporary storage of input stroke control points */ diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c index 010bf6f746c..64f9ad0283e 100644 --- a/source/blender/src/sculptmode.c +++ b/source/blender/src/sculptmode.c @@ -65,6 +65,7 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_sculpt.h" #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_colortools.h" @@ -168,7 +169,6 @@ typedef struct ProjVert { char inside; } ProjVert; -static ProjVert *projverts= NULL; static Object *active_ob= NULL; SculptData *sculpt_data(void) @@ -192,135 +192,13 @@ SculptSession *sculpt_session(void) * Allocate/initialize/free data */ -// Default curve approximates 0.5 * (cos(pi * x) + 1), with 0 <= x <= 1; -void sculpt_reset_curve(SculptData *sd) -{ - CurveMap *cm = NULL; - - if(!sd->cumap) - sd->cumap = curvemapping_add(1, 0, 0, 1, 1); - - cm = sd->cumap->cm; - - if(cm->curve) - MEM_freeN(cm->curve); - cm->curve= MEM_callocN(6*sizeof(CurveMapPoint), "curve points"); - cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; - cm->totpoint= 6; - cm->curve[0].x= 0; - cm->curve[0].y= 1; - cm->curve[1].x= 0.1; - cm->curve[1].y= 0.97553; - cm->curve[2].x= 0.3; - cm->curve[2].y= 0.79389; - cm->curve[3].x= 0.9; - cm->curve[3].y= 0.02447; - cm->curve[4].x= 0.7; - cm->curve[4].y= 0.20611; - cm->curve[5].x= 1; - cm->curve[5].y= 0; -} - -/* Initialize 'permanent' sculpt data that is saved with file kept after - switching out of sculptmode. */ -void sculptmode_init(Scene *sce) -{ - SculptData *sd; - - if(!sce) { - error("Unable to initialize sculptmode: bad scene"); - return; - } - - sd= &sce->sculptdata; - - if(sd->cumap) - curvemapping_free(sd->cumap); - - memset(sd, 0, sizeof(SculptData)); - - sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size = - sd->inflatebrush.size = sd->grabbrush.size = - sd->layerbrush.size = sd->flattenbrush.size = 50; - sd->drawbrush.strength = sd->smoothbrush.strength = - sd->pinchbrush.strength = sd->inflatebrush.strength = - sd->grabbrush.strength = sd->layerbrush.strength = - sd->flattenbrush.strength = 25; - sd->drawbrush.dir = sd->pinchbrush.dir = sd->inflatebrush.dir = sd->layerbrush.dir= 1; - sd->drawbrush.airbrush = sd->smoothbrush.airbrush = - sd->pinchbrush.airbrush = sd->inflatebrush.airbrush = - sd->layerbrush.airbrush = sd->flattenbrush.airbrush = 0; - sd->drawbrush.view= 0; - sd->brush_type= DRAW_BRUSH; - sd->texact= -1; - sd->texfade= 1; - sd->averaging= 1; - sd->texsep= 0; - sd->texrept= SCULPTREPT_DRAG; - sd->flags= SCULPT_DRAW_BRUSH; - sd->tablet_size=3; - sd->tablet_strength=10; - sd->rake=0; - sculpt_reset_curve(sd); -} - -void sculptmode_free_session(Scene *); void sculpt_init_session(void) { if(sculpt_data()->session) - sculptmode_free_session(G.scene); + sculptsession_free(G.scene); sculpt_data()->session= MEM_callocN(sizeof(SculptSession), "SculptSession"); } -void sculptmode_free_vertexusers(SculptSession *ss) -{ - if(ss && ss->vertex_users){ - MEM_freeN(ss->vertex_users); - MEM_freeN(ss->vertex_users_mem); - ss->vertex_users= NULL; - ss->vertex_users_mem= NULL; - ss->vertex_users_size= 0; - } -} - -void sculptmode_propset_end(SculptSession *ss, int); -void sculptmode_free_session(Scene *sce) -{ - SculptSession *ss= sce->sculptdata.session; - if(ss) { - sculptmode_free_vertexusers(ss); - if(ss->texcache) - MEM_freeN(ss->texcache); - sculptmode_propset_end(ss, 1); - MEM_freeN(ss); - sce->sculptdata.session= NULL; - } -} - -void sculptmode_free_all(Scene *sce) -{ - SculptData *sd= &sce->sculptdata; - int a; - - sculptmode_free_session(sce); - - if(projverts) { - MEM_freeN(projverts); - projverts = NULL; - } - - for(a=0; amtex[a]; - if(mtex) { - if(mtex->tex) mtex->tex->id.us--; - MEM_freeN(mtex); - } - } - - curvemapping_free(sd->cumap); - sd->cumap = NULL; -} - /* vertex_users is an array of Lists that store all the faces that use a particular vertex. vertex_users is in the same order as mesh.mvert */ void calc_vertex_users() @@ -330,7 +208,7 @@ void calc_vertex_users() IndexNode *node= NULL; Mesh *me= get_mesh(OBACT); - sculptmode_free_vertexusers(ss); + sculpt_vertexusers_free(ss); /* For efficiency, use vertex_users_mem as a memory pool (may be larger than necessary if mesh has triangles, but only one alloc is needed.) */ @@ -384,7 +262,9 @@ void init_sculptmatrices() glPushMatrix(); glMultMatrixf(OBACT->obmat); - bgl_get_mats(&ss->mats); + if(!ss->mats) + ss->mats = MEM_callocN(sizeof(bglMats), "sculpt bglmats"); + bgl_get_mats(ss->mats); glPopMatrix(); @@ -419,8 +299,8 @@ vec3f unproject(const short x, const short y, const float z) double ux, uy, uz; vec3f p; - gluUnProject(x,y,z, ss->mats.modelview, ss->mats.projection, - (GLint *)ss->mats.viewport, &ux, &uy, &uz ); + gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection, + (GLint *)ss->mats->viewport, &ux, &uy, &uz ); p.x= ux; p.y= uy; p.z= uz; @@ -433,8 +313,8 @@ void project(const float v[3], short p[2]) SculptSession *ss= sculpt_session(); double ux, uy, uz; - gluProject(v[0],v[1],v[2], ss->mats.modelview, ss->mats.projection, - (GLint *)ss->mats.viewport, &ux, &uy, &uz); + gluProject(v[0],v[1],v[2], ss->mats->modelview, ss->mats->projection, + (GLint *)ss->mats->viewport, &ux, &uy, &uz); p[0]= ux; p[1]= uy; } @@ -867,7 +747,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin across the symmetry axis in order to project it. This insures that the brush texture will be oriented correctly. */ if(!e->symm) - pv= projverts[vindex]; + pv= ss->projverts[vindex]; else { float co[3]; VecCopyf(co, point); @@ -934,6 +814,7 @@ void sculpt_add_damaged_rect(EditData *e) const float radius= brush_size(); RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode"); Mesh *me= get_mesh(OBACT); + SculptSession *ss = sculpt_session(); unsigned i; /* Find center */ @@ -947,10 +828,10 @@ void sculpt_add_damaged_rect(EditData *e) /* Update insides */ for(i=0; itotvert; ++i) { - if(!projverts[i].inside) { - if(projverts[i].co[0] > rn->r.xmin && projverts[i].co[1] > rn->r.ymin && - projverts[i].co[0] < rn->r.xmax && projverts[i].co[1] < rn->r.ymax) { - projverts[i].inside= 1; + if(!ss->projverts[i].inside) { + if(ss->projverts[i].co[0] > rn->r.xmin && ss->projverts[i].co[1] > rn->r.ymin && + ss->projverts[i].co[0] < rn->r.xmax && ss->projverts[i].co[1] < rn->r.ymax) { + ss->projverts[i].inside= 1; } } } @@ -1005,7 +886,7 @@ void do_brush_action(EditData e) if(!e.grabdata || (e.grabdata && e.grabdata->firsttime)) { for(i=0; itotvert; ++i) { /* Projverts.inside provides a rough bounding box */ - if(projverts[i].inside) { + if(ss->projverts[i].inside) { vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : me->mvert[i].co; av_dist= VecLenf(&e.center.x,vert); if(av_dist < e.size) { @@ -1172,13 +1053,13 @@ void calc_damaged_verts(ListBase *damaged_verts, GrabData *grabdata) } } -void projverts_clear_inside() +void projverts_clear_inside(SculptSession *ss) { Mesh *me = get_mesh(OBACT); if(me) { int i; for(i = 0; i < me->totvert; ++i) - projverts[i].inside = 0; + ss->projverts[i].inside = 0; } } @@ -1196,7 +1077,7 @@ BrushData *sculptmode_brush(void) sd->brush_type==FLATTEN_BRUSH ? &sd->flattenbrush : NULL); if(!bd) { - sculptmode_init(G.scene); + sculptdata_init(G.scene); bd = &sd->drawbrush; } @@ -1604,19 +1485,20 @@ void sculptmode_selectbrush_menu(void) void sculptmode_update_all_projverts(float *vertcosnos) { + SculptSession *ss = sculpt_session(); Mesh *me= get_mesh(OBACT); unsigned i; - if(!projverts) - projverts = MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts"); + if(!ss->projverts) + ss->projverts = MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts"); for(i=0; itotvert; ++i) { - project(vertcosnos ? &vertcosnos[i * 6] : me->mvert[i].co, projverts[i].co); - projverts[i].inside= 0; + project(vertcosnos ? &vertcosnos[i * 6] : me->mvert[i].co, ss->projverts[i].co); + ss->projverts[i].inside= 0; } } -void sculptmode_draw_wires(int only_damaged, Mesh *me) +void sculptmode_draw_wires(SculptSession *ss, int only_damaged, Mesh *me) { int i; @@ -1627,7 +1509,7 @@ void sculptmode_draw_wires(int only_damaged, Mesh *me) for(i=0; itotedge; i++) { MEdge *med= &me->medge[i]; - if((!only_damaged || (projverts[med->v1].inside || projverts[med->v2].inside)) && + if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) && (med->flag & ME_EDGEDRAW)) { glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1); } @@ -1641,6 +1523,7 @@ void sculptmode_draw_mesh(int only_damaged) { Mesh *me= get_mesh(OBACT); int i, j, dt, drawCurrentMat = 1, matnr= -1; + SculptSession *ss = sculpt_session(); persp(PERSP_VIEW); mymultmatrix(OBACT->obmat); @@ -1670,7 +1553,7 @@ void sculptmode_draw_mesh(int only_damaged) inside the area(s) modified by the brush */ if(only_damaged) { for(j=0; j<(f->v4?4:3); ++j) { - if(projverts[*((&f->v1)+j)].inside) { + if(ss->projverts[*((&f->v1)+j)].inside) { inside= 1; break; } @@ -1688,7 +1571,7 @@ void sculptmode_draw_mesh(int only_damaged) glColorMask(1,1,1,1); if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE)) - sculptmode_draw_wires(only_damaged, me); + sculptmode_draw_wires(ss, only_damaged, me); glDisable(GL_DEPTH_TEST); } @@ -1754,11 +1637,11 @@ void sculpt(void) /* Check that vertex users are up-to-date */ if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != get_mesh(ob)->totvert) { - sculptmode_free_vertexusers(ss); + sculpt_vertexusers_free(ss); calc_vertex_users(); - if(projverts) - MEM_freeN(projverts); - projverts = NULL; + if(ss->projverts) + MEM_freeN(ss->projverts); + ss->projverts = NULL; active_ob= ob; } @@ -1866,7 +1749,7 @@ void sculpt(void) sculptmode_draw_mesh(1); glAccum(GL_LOAD, 1); - projverts_clear_inside(); + projverts_clear_inside(ss); persp(PERSP_WIN); glDisable(GL_DEPTH_TEST); @@ -1951,9 +1834,9 @@ void set_sculptmode(void) G.f &= ~G_SCULPTMODE; - sculptmode_free_session(G.scene); + sculptsession_free(G.scene); if(me && me->pv) - sculptmode_pmv_off(me); + mesh_pmv_off(OBACT, me); } else { G.f |= G_SCULPTMODE; @@ -1974,77 +1857,9 @@ void set_sculptmode(void) } /* Partial Mesh Visibility */ -PartialVisibility *sculptmode_copy_pmv(PartialVisibility *pmv) -{ - PartialVisibility *n= MEM_dupallocN(pmv); - n->vert_map= MEM_dupallocN(pmv->vert_map); - n->edge_map= MEM_dupallocN(pmv->edge_map); - n->old_edges= MEM_dupallocN(pmv->old_edges); - n->old_faces= MEM_dupallocN(pmv->old_faces); - return n; -} - -void sculptmode_pmv_free(PartialVisibility *pv) -{ - MEM_freeN(pv->vert_map); - MEM_freeN(pv->edge_map); - MEM_freeN(pv->old_faces); - MEM_freeN(pv->old_edges); - MEM_freeN(pv); -} - -void sculptmode_revert_pmv(Mesh *me) -{ - if(me->pv) { - unsigned i; - MVert *nve, *old_verts; - - active_ob= NULL; - - /* Reorder vertices */ - nve= me->mvert; - old_verts = MEM_mallocN(sizeof(MVert)*me->pv->totvert,"PMV revert verts"); - for(i=0; ipv->totvert; ++i) - old_verts[i]= nve[me->pv->vert_map[i]]; - - /* Restore verts, edges and faces */ - CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); - CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); - CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, old_verts, me->pv->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->pv->old_edges, me->pv->totedge); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->pv->old_faces, me->pv->totface); - mesh_update_customdata_pointers(me); - - me->totvert= me->pv->totvert; - me->totedge= me->pv->totedge; - me->totface= me->pv->totface; - - me->pv->old_edges= NULL; - me->pv->old_faces= NULL; - - /* Free maps */ - MEM_freeN(me->pv->edge_map); - me->pv->edge_map= NULL; - MEM_freeN(me->pv->vert_map); - me->pv->vert_map= NULL; - - DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); - } -} - -void sculptmode_pmv_off(Mesh *me) -{ - if(me->pv) { - sculptmode_revert_pmv(me); - MEM_freeN(me->pv); - me->pv= NULL; - } -} /* mode: 0=hide outside selection, 1=hide inside selection */ -void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode) +static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode) { Mesh *me= get_mesh(ob); vec3f hidebox[6]; @@ -2085,7 +1900,7 @@ void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode) for(i=0; ipv->totvert; ++i) { old_map[i]= me->pv->vert_map[i]totvert?0:1; } - sculptmode_revert_pmv(me); + mesh_pmv_revert(ob, me); } /* Kill sculpt data */ @@ -2202,7 +2017,7 @@ void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode) DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); } -rcti sculptmode_pmv_box() +static rcti sculptmode_pmv_box() { short down[2], mouse[2]; rcti ret; @@ -2257,7 +2072,7 @@ void sculptmode_pmv(int mode) sculptmode_do_pmv(ob,&hb_2d,mode); } - else sculptmode_pmv_off(get_mesh(ob)); + else mesh_pmv_off(ob, get_mesh(ob)); scrarea_do_windraw(curarea); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 486ebfa7010..ca0ee8f90ca 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -89,6 +89,7 @@ #include "BKE_multires.h" #include "BKE_node.h" #include "BKE_scene.h" +#include "BKE_sculpt.h" #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */ @@ -1509,7 +1510,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) case HKEY: if(G.qual==LR_ALTKEY) { waitcursor(1); - sculptmode_pmv_off(get_mesh(ob)); + mesh_pmv_off(ob, get_mesh(ob)); BIF_undo_push("Partial mesh hide"); allqueue(REDRAWVIEW3D,0); waitcursor(0); diff --git a/source/blender/src/view.c b/source/blender/src/view.c index d23b6f1d8f4..52f9ff06227 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -66,6 +66,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_sculpt.h" #include "BKE_utildefines.h" #include "BIF_editparticle.h" From fc2cf13fc6b66caf09e610a83b793fc8e7da09a1 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 26 Dec 2007 23:08:00 +0000 Subject: [PATCH 61/99] == Sculpt == Fixed a memory leak when using the interactive brush resize tool. --- source/blender/blenkernel/BKE_sculpt.h | 29 +++++++++++++++++++++ source/blender/blenkernel/intern/scene.c | 9 +++++++ source/blender/blenloader/intern/readfile.c | 1 + source/blender/include/BDR_sculptmode.h | 21 +-------------- source/blender/src/sculptmode.c | 13 +++++---- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/BKE_sculpt.h b/source/blender/blenkernel/BKE_sculpt.h index 61b8dc071aa..d539bcf5e8c 100644 --- a/source/blender/blenkernel/BKE_sculpt.h +++ b/source/blender/blenkernel/BKE_sculpt.h @@ -27,6 +27,34 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef BKE_SCULPT_H +#define BKE_SCULPT_H + +struct NumInput; +struct Scene; +struct SculptData; +struct SculptSession; + +typedef enum PropsetMode { + PropsetNone = 0, + PropsetSize, + PropsetStrength, + PropsetTexRot +} PropsetMode; + +typedef struct PropsetData { + PropsetMode mode; + unsigned int tex; + short origloc[2]; + float *texdata; + + short origsize; + char origstrength; + float origtexrot; + + struct NumInput *num; +} PropsetData; + typedef struct SculptSession { struct ProjVert *projverts; @@ -62,3 +90,4 @@ void sculptsession_free(struct Scene *sce); void sculpt_vertexusers_free(struct SculptSession *ss); void sculpt_reset_curve(struct SculptData *sd); +#endif diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 88dca65f594..47640ad07ae 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -659,6 +659,15 @@ void sculptsession_free(Scene *sce) MEM_freeN(ss->projverts); if(ss->mats) MEM_freeN(ss->mats); + + if(ss->propset) { + if(ss->propset->texdata) + MEM_freeN(ss->propset->texdata); + if(ss->propset->num) + MEM_freeN(ss->propset->num); + MEM_freeN(ss->propset); + } + sculpt_vertexusers_free(ss); if(ss->texcache) MEM_freeN(ss->texcache); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f8f0395300c..043febbbc75 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -136,6 +136,7 @@ #include "BKE_sca.h" // for init_actuator #include "BKE_scene.h" #include "BKE_softbody.h" // sbNew() +#include "BKE_sculpt.h" #include "BKE_texture.h" // for open_plugin_tex #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BKE_idprop.h" diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h index 884f1000b1f..e15c1fb7063 100644 --- a/source/blender/include/BDR_sculptmode.h +++ b/source/blender/include/BDR_sculptmode.h @@ -32,6 +32,7 @@ #include "DNA_listBase.h" #include "DNA_vec_types.h" +#include "BKE_sculpt.h" #include "transform.h" struct uiBlock; @@ -47,26 +48,6 @@ struct ScrArea; struct SculptData; struct SculptStroke; -typedef enum PropsetMode { - PropsetNone = 0, - PropsetSize, - PropsetStrength, - PropsetTexRot -} PropsetMode; - -typedef struct PropsetData { - PropsetMode mode; - unsigned int tex; - short origloc[2]; - float *texdata; - - short origsize; - char origstrength; - float origtexrot; - - NumInput num; -} PropsetData; - struct SculptSession *sculpt_session(void); struct SculptData *sculpt_data(void); diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c index 64f9ad0283e..f3bfb645315 100644 --- a/source/blender/src/sculptmode.c +++ b/source/blender/src/sculptmode.c @@ -1313,6 +1313,7 @@ void sculptmode_propset_end(SculptSession *ss, int cancel) set_tex_angle(pd->origtexrot); } glDeleteTextures(1, &pd->tex); + MEM_freeN(pd->num); MEM_freeN(pd->texdata); MEM_freeN(pd); ss->propset= NULL; @@ -1353,7 +1354,9 @@ void sculptmode_propset_init(PropsetMode mode) sculptmode_propset_calctex(); - pd->num.idx_max= 0; + if(!pd->num) + pd->num = MEM_callocN(sizeof(NumInput), "propset numinput"); + pd->num->idx_max= 0; } pd->mode= mode; @@ -1391,11 +1394,11 @@ void sculptmode_propset(unsigned short event) BrushData *brush= sculptmode_brush(); char valset= 0; - handleNumInput(&pd->num, event); + handleNumInput(pd->num, event); - if(hasNumInput(&pd->num)) { + if(hasNumInput(pd->num)) { float val; - applyNumInput(&pd->num, &val); + applyNumInput(pd->num, &val); if(pd->mode==PropsetSize) brush->size= val; else if(pd->mode==PropsetStrength) @@ -1409,7 +1412,7 @@ void sculptmode_propset(unsigned short event) switch(event) { case MOUSEX: case MOUSEY: - if(!hasNumInput(&pd->num)) { + if(!hasNumInput(pd->num)) { char ctrl= G.qual & LR_CTRLKEY; getmouseco_areawin(mouse); tmp[0]= pd->origloc[0]-mouse[0]; From 55d49ed63b524f5c11e66af996995114017f5dc0 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Thu, 27 Dec 2007 07:27:03 +0000 Subject: [PATCH 62/99] == Multires == Fixed a crash on adding a UV layer to a multires mesh while in editmode. --- source/blender/include/multires.h | 1 + source/blender/src/buttons_editing.c | 2 ++ source/blender/src/multires.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/include/multires.h b/source/blender/include/multires.h index 7d0bed47d53..e4726c02d7e 100644 --- a/source/blender/include/multires.h +++ b/source/blender/include/multires.h @@ -48,6 +48,7 @@ void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned void multires_make(void *ob, void *me); void multires_delete(void *ob, void *me); void multires_level_to_editmesh(struct Object *ob, struct Mesh *me, const int render); +void multires_finish_mesh_update(struct Object *ob); void multires_subdivide(void *ob, void *me); void multires_del_lower(void *ob, void *me); void multires_del_higher(void *ob, void *me); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index e1c60f8f493..1c9f935e9d6 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -739,6 +739,7 @@ static void delete_customdata_layer(void *data1, void *data2) if(me && me->mr) { multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]); multires_level_to_editmesh(OBACT, me, 0); + multires_finish_mesh_update(OBACT); } else if(G.obedit) { EM_free_data_layer(data, type); @@ -4497,6 +4498,7 @@ void do_meshbuts(unsigned short event) if(me && me->mr) { multires_add_layer(me, &me->mr->fdata, CD_MTFACE, layernum); multires_level_to_editmesh(ob, me, 0); + multires_finish_mesh_update(ob); } else if(G.obedit) { EM_add_data_layer(&em->fdata, CD_MTFACE); diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c index 67485529525..64edfb5f6cc 100644 --- a/source/blender/src/multires.c +++ b/source/blender/src/multires.c @@ -349,7 +349,7 @@ void multires_del_higher(void *ob, void *me) BIF_undo_push("Multires delete higher"); } -static void multires_finish_mesh_update(Object *ob) +void multires_finish_mesh_update(Object *ob) { /* friendly check for background render */ if(G.background==0) { From 0dc38a5bd93bf3197083db424c7cd34d402bc9ad Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 27 Dec 2007 08:36:27 +0000 Subject: [PATCH 63/99] == PoseLib - Added 2 features == * When previewing poses, it is now possible to manipulate the view to look at the pose from another angle. It is a known issue, that the normal header displays when using the MMB to do so. * Added a tool to "validate" or sync its PoseLib data to the keys stored in the Action. --- source/blender/include/BIF_poselib.h | 2 + source/blender/include/BIF_space.h | 1 + source/blender/include/butspace.h | 1 + source/blender/makesdna/DNA_action_types.h | 2 +- source/blender/src/buttons_editing.c | 12 +- source/blender/src/poselib.c | 225 ++++++++++++++++----- 6 files changed, 195 insertions(+), 48 deletions(-) diff --git a/source/blender/include/BIF_poselib.h b/source/blender/include/BIF_poselib.h index 213714cf09a..2d5978e422e 100644 --- a/source/blender/include/BIF_poselib.h +++ b/source/blender/include/BIF_poselib.h @@ -34,6 +34,7 @@ #define BIF_POSELIB_H struct Object; +struct bAction; struct bPoseLib; struct bPoseLibRef; @@ -42,6 +43,7 @@ void poselib_unique_pose_name(struct bPoseLib *pl, char name[]); int poselib_get_free_index(struct bPoseLib *pl); struct bPoseLib *poselib_init_new(struct Object *ob); +void poselib_validate_act(struct bAction *act); void poselib_remove_pose(struct Object *ob, struct bPoseLibRef *plr); void poselib_rename_pose(struct Object *ob); diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h index 855773b3497..78f5ff90a4e 100644 --- a/source/blender/include/BIF_space.h +++ b/source/blender/include/BIF_space.h @@ -120,6 +120,7 @@ extern void force_draw_plus(int type, int header); extern void freespacelist(struct ScrArea *sa); extern void handle_view3d_around(void); extern void handle_view3d_lock(void); +extern void handle_view_middlemouse(void); extern void init_v2d_oops(struct ScrArea *, struct SpaceOops *); extern void initipo(struct ScrArea *sa); extern void newspace(struct ScrArea *sa, int type); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 4de9064b0bd..052da648770 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -515,6 +515,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_POSELIB_ADDPOSE 2311 #define B_POSELIB_REPLACEP 2312 #define B_POSELIB_REMOVEP 2313 +#define B_POSELIB_VALIDATE 2314 /* *********************** */ #define B_CAMBUTS 2500 diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 9921d784984..ec763ad606c 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -105,7 +105,7 @@ typedef struct bPoseLibRef { struct bPoseLibRef *next, *prev; int frame; /* frame in the action to look for this pose */ char name[32]; /* name of the pose */ - int pad; + int flag; /* temporary settings for this pose */ } bPoseLibRef; /* PoseLib data for Action diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 1c9f935e9d6..3e50b9c5ba9 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3757,6 +3757,14 @@ void do_armbuts(unsigned short event) } allqueue(REDRAWBUTSEDIT, 0); break; + case B_POSELIB_VALIDATE: + if (ob && ob->pose) { + bAction *act= ob->pose->poselib; + + poselib_validate_act(act); + } + allqueue(REDRAWBUTSEDIT, 0); + break; } } @@ -4987,8 +4995,8 @@ static void editing_panel_links(Object *ob) uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, REDRAWBUTSEDIT, "AC:", xco, 130, 140, 20, &pose->poselib, "Action to use as PoseLib"); } } - uiDefBut(block, BUT, B_POSELIB_NEW, "New PoseLib", xco,110,140,20, 0, 0, 0, 0, 0, "Creates a new PoseLib"); - + uiDefBut(block, BUT, B_POSELIB_NEW, "New PoseLib", xco,110,70,20, 0, 0, 0, 0, 0, "Creates a new PoseLib"); + uiDefBut(block, BUT, B_POSELIB_VALIDATE, "Validate PoseLib", xco+70,110,70,20, 0, 0, 0, 0, 0, "Validates active PoseLib"); /* poselib pose editing controls */ if ((act) && (act->poselib)) { diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index 6e088bbf03e..af59f6c55c4 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -1,4 +1,30 @@ - +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + #include #include #include @@ -36,11 +62,14 @@ //#include "BIF_keyframing.h" #include "BSE_editipo.h" +#include "BDR_drawaction.h" + #include "BIF_poselib.h" #include "BIF_interface.h" #include "BIF_editaction.h" #include "BIF_space.h" #include "BIF_screen.h" +#include "BIF_toets.h" #include "BIF_toolbox.h" #include "blendef.h" @@ -205,6 +234,75 @@ bPoseLib *poselib_init_new (Object *ob) } +/* This tool automagically generates/validates poselib data so that it corresponds to the data + * in the action. This is for use in making existing actions usable as poselibs. + */ +void poselib_validate_act (bAction *act) +{ + ListBase keys = {NULL, NULL}; + ActKeyColumn *ak; + bPoseLib *pl; + bPoseLibRef *plr, *plrn; + + /* validate action and poselib */ + if (act == NULL) { + error("No Action to validate"); + return; + } + + if (act->poselib == NULL) + act->poselib= MEM_callocN(sizeof(bPoseLib), "bPoseLib"); + pl= act->poselib; + + /* determine which frames have keys */ + action_to_keylist(act, &keys, NULL); + + /* for each key, make sure there is a correspnding pose */ + for (ak= keys.first; ak; ak= ak->next) { + /* check if any pose matches this */ + for (plr= pl->poses.first; plr; plr= plr->next) { + if (IS_EQ(plr->frame, ak->cfra)) { + plr->flag = 1; + break; + } + } + + /* add new if none found */ + if (plr == NULL) { + char name[32]; + + /* add pose to poselib */ + plr= MEM_callocN(sizeof(bPoseLibRef), "bPoseLibRef"); + + strcpy(name, "Pose"); + poselib_unique_pose_name(pl, name); + BLI_strncpy(plr->name, name, sizeof(plr->name)); + + plr->frame= (int)ak->cfra; + plr->flag= 1; + + BLI_addtail(&pl->poses, plr); + } + } + + /* remove all untagged poses (unused), and remove all tags */ + for (plr= pl->poses.first; plr; plr= plrn) { + plrn= plr->next; + + if (plr->flag == 0) + BLI_freelinkN(&pl->poses, plr); + else + plr->flag = 0; + } + + /* free temp memory */ + BLI_freelistN(&keys); + + BIF_undo_push("PoseLib Validate Action"); +} + +/* ************************************************************* */ + /* This function adds an ipo-curve of the right type where it's needed */ static IpoCurve *poselib_verify_icu (Ipo *ipo, int adrcode) { @@ -528,7 +626,7 @@ static void poselib_apply_pose (Object *ob, bPoseLibRef *plr, char headerstr[]) /* apply this achan? */ if (achan->ipo) { - /* find a keyframe at this frame */ + /* find a keyframe at this frame - users may not have defined the pose on every channel, so this is necessary */ for (icu= achan->ipo->curve.first; icu; icu= icu->next) { BezTriple *bezt; int i; @@ -616,13 +714,20 @@ static void poselib_keytag_pose (Object *ob) /* ---------------------------- */ -/* defines for psoelib_preview_poses --> ret_val values */ +/* defines for poselib_preview_poses --> ret_val values */ enum { PL_PREVIEW_RUNNING = 0, PL_PREVIEW_CONFIRM, PL_PREVIEW_CANCEL }; +/* defines for poselib_preview_poses --> redraw values */ +enum { + PL_PREVIEW_NOREDRAW = 0, + PL_PREVIEW_REDRAWALL, + PL_PREVIEW_REDRAWHEADER, +}; + /* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown */ void poselib_preview_poses (Object *ob) { @@ -665,45 +770,48 @@ void poselib_preview_poses (Object *ob) while (ret_val == PL_PREVIEW_RUNNING) { /* preview a pose */ if (redraw) { - /* don't clear pose if firsttime */ - if (firsttime == 0) - poselib_backup_restore(&backups); - else - firsttime = 0; + /* only recalc pose (and its dependencies) if pose has changed */ + if (redraw == PL_PREVIEW_REDRAWALL) { + /* don't clear pose if firsttime */ + if (firsttime == 0) + poselib_backup_restore(&backups); + else + firsttime = 0; + + /* pose should be the right one to draw */ + poselib_apply_pose(ob, plr, headerstr); - /* pose should be the right one to draw */ - poselib_apply_pose(ob, plr, headerstr); - - /* old optimize trick... this enforces to bypass the depgraph - * - note: code copied from transform_generics.c -> recalcData() - */ - if ((arm->flag & ARM_DELAYDEFORM)==0) { - Base *base; - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ - - /* bah, softbody exception... recalcdata doesnt reset */ - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->recalc & OB_RECALC_DATA) - if (modifiers_isSoftbodyEnabled(base->object)) { - base->object->softflag |= OB_SB_REDO; + /* old optimize trick... this enforces to bypass the depgraph + * - note: code copied from transform_generics.c -> recalcData() + */ + if ((arm->flag & ARM_DELAYDEFORM)==0) { + Base *base; + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + + /* bah, softbody exception... recalcdata doesnt reset */ + for (base= FIRSTBASE; base; base= base->next) { + if (base->object->recalc & OB_RECALC_DATA) + if (modifiers_isSoftbodyEnabled(base->object)) { + base->object->softflag |= OB_SB_REDO; + } } } + else + where_is_pose(ob); } - else - where_is_pose(ob); /* do header print */ sprintf(headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", plr->name); headerprint(headerstr); - /* redraw... */ + /* force drawing of view + clear redraw flag */ force_draw(0); - redraw= 0; + redraw= PL_PREVIEW_NOREDRAW; } /* essential for idling subloop */ - if( qtest()==0) PIL_sleep_ms(2); + if (qtest() == 0) PIL_sleep_ms(2); /* emptying queue and reading events */ while ( qtest() ) { @@ -711,22 +819,49 @@ void poselib_preview_poses (Object *ob) /* event processing */ if (val) { - /* exit */ - if (ELEM(event, ESCKEY, RIGHTMOUSE)) - ret_val= PL_PREVIEW_CANCEL; - else if (ELEM3(event, LEFTMOUSE, RETKEY, SPACEKEY)) - ret_val= PL_PREVIEW_CONFIRM; - - /* change pose */ - else if (ELEM(event, PAGEUPKEY, WHEELUPMOUSE)) { - /* find previous pose - go back to end of list if no previous (cyclic) */ - plr= (plr->prev) ? plr->prev : pl->poses.last; - redraw= 1; - } - else if (ELEM(event, PAGEDOWNKEY, WHEELDOWNMOUSE)) { - /* find next pose - go back to start of list if no next (cyclic) */ - plr= (plr->next) ? plr->next : pl->poses.first; - redraw= 1; + switch (event) { + /* exit - cancel */ + case ESCKEY: + case RIGHTMOUSE: + ret_val= PL_PREVIEW_CANCEL; + break; + + /* exit - confirm */ + case LEFTMOUSE: + case RETKEY: + case SPACEKEY: + ret_val= PL_PREVIEW_CONFIRM; + break; + + /* change to previous pose - go back to end of list if no previous (cyclic) */ + case PAGEUPKEY: + case WHEELUPMOUSE: + plr= (plr->prev) ? plr->prev : pl->poses.last; + redraw= PL_PREVIEW_REDRAWALL; + break; + + /* change to next pose - go back to start of list if no next (cyclic) */ + case PAGEDOWNKEY: + case WHEELDOWNMOUSE: + plr= (plr->next) ? plr->next : pl->poses.first; + redraw= PL_PREVIEW_REDRAWALL; + break; + + /* view manipulation */ + case MIDDLEMOUSE: + // there's a little bug here that causes the normal header to get drawn while view is manipulated + handle_view_middlemouse(); + redraw= PL_PREVIEW_REDRAWHEADER; + break; + + case PAD0: case PAD1: case PAD2: case PAD3: case PAD4: + case PAD5: case PAD6: case PAD7: case PAD8: case PAD9: + case PADPLUSKEY: + case PADMINUS: + case PADENTER: + persptoetsen(event); + redraw= PL_PREVIEW_REDRAWHEADER; + break; } } } From d06dc00af908584a02291cffb8704ac61caa12df Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Thu, 27 Dec 2007 10:17:33 +0000 Subject: [PATCH 64/99] Toggle links tool for Node Editor This commit adds a new tool, Toggle Links, to the node editor. This tool allows the user to toggle the status (linked/not linked) between desired sockets. The tool can be used either by using the f key or the menus. This functionality is analogue to one found in object editing modes except for its additional toggle functionality. To use this tool, the user has to first select an input and an output socket. Selecting is done by clicking with right mouse button on a socket. After the tool has been invoked, the link between those two sockets is toggled. The result may vary based on existing linkage. There can be only one input and one output selected at maximum in a node tree. This means that if the user selects a socket while one of the same type is already selected, the old one will be deselected. The tool complements the current way of connecting nodes. One possible use for it is to use it to review output of nodes by using a viewer node. Just select wanted input socket of a viewer node, set it visible and use selection of an output socket in conjuction with f key to show the output in the viewer node. Select another output and hit f to see its output and so on. --- source/blender/blenkernel/BKE_node.h | 3 + source/blender/blenkernel/intern/node.c | 57 ++++++++-- source/blender/include/BSE_node.h | 1 + source/blender/makesdna/DNA_node_types.h | 7 +- source/blender/src/drawnode.c | 73 +++++++----- source/blender/src/editnode.c | 136 ++++++++++++++++++----- source/blender/src/header_node.c | 7 ++ source/blender/src/toolbox.c | 2 + 8 files changed, 222 insertions(+), 64 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 2ffa1d205da..b9df1e45bae 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -143,6 +143,7 @@ void nodeVerifyType(struct bNodeTree *ntree, struct bNode *node); void nodeAddToPreview(struct bNode *, float *, int, int); +void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup); void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); @@ -150,6 +151,8 @@ struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock); void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link); +int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex); + struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to); int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 651115b7180..4bcacae9fc5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -483,6 +483,20 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) BLI_addtail(&ngroup->nodes, node); node->locx-= 0.5f*(min[0]+max[0]); node->locy-= 0.5f*(min[1]+max[1]); + + /* set selin and selout of the nodetree */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ngroup->selin= sock; + break; + } + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ngroup->selout= sock; + break; + } + } } } @@ -653,7 +667,8 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup) } } -static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex) +/* finds a node based on given socket */ +int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex) { bNode *node; bNodeSocket *tsock; @@ -671,13 +686,15 @@ static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **n if(tsock) break; } + if(node) { *nodep= node; - *sockindex= index; - } - else { - *nodep= NULL; + if(sockindex) *sockindex= index; + return 1; } + + *nodep= NULL; + return 0; } /* returns 1 if its OK */ @@ -717,7 +734,7 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) for(link= ntree->links.first; link; link= link->next) { if(link->tonode==gnode) { /* link->tosock->tosock is on the node we look for */ - find_node_with_socket(ngroup, link->tosock->tosock, &nextn, &index); + nodeFindNode(ngroup, link->tosock->tosock, &nextn, &index); if(nextn==NULL) printf("wrong stuff!\n"); else if(nextn->new_node==NULL) printf("wrong stuff too!\n"); else { @@ -727,7 +744,7 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) } else if(link->fromnode==gnode) { /* link->fromsock->tosock is on the node we look for */ - find_node_with_socket(ngroup, link->fromsock->tosock, &nextn, &index); + nodeFindNode(ngroup, link->fromsock->tosock, &nextn, &index); if(nextn==NULL) printf("1 wrong stuff!\n"); else if(nextn->new_node==NULL) printf("1 wrong stuff too!\n"); else { @@ -898,6 +915,28 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select) nnode->flag |= NODE_SELECT; } node->flag &= ~NODE_ACTIVE; + + /* deselect original sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL; + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL; + } + + /* set tree selin and selout to new sockets */ + for(sock= nnode->inputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ntree->selin= sock; + break; + } + } + for(sock= nnode->outputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ntree->selout= sock; + break; + } + } } if(node==last) break; } @@ -941,7 +980,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select) /* ************** Free stuff ********** */ /* goes over entire tree */ -static void node_unlink_node(bNodeTree *ntree, bNode *node) +void nodeUnlinkNode(bNodeTree *ntree, bNode *node) { bNodeLink *link, *next; bNodeSocket *sock; @@ -985,7 +1024,7 @@ static void composit_free_node_cache(bNode *node) void nodeFreeNode(bNodeTree *ntree, bNode *node) { - node_unlink_node(ntree, node); + nodeUnlinkNode(ntree, node); BLI_remlink(&ntree->nodes, node); /* since it is called while free database, node->id is undefined */ diff --git a/source/blender/include/BSE_node.h b/source/blender/include/BSE_node.h index 171a277e8e6..5862918953c 100644 --- a/source/blender/include/BSE_node.h +++ b/source/blender/include/BSE_node.h @@ -72,6 +72,7 @@ void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode); void node_hide(struct SpaceNode *snode); void node_read_renderlayers(struct SpaceNode *snode); void clear_scene_in_nodes(struct Scene *sce); +void node_toggle_link(struct SpaceNode *snode); void node_transform_ext(int mode, int unused); void node_shader_default(struct Material *ma); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 5f20939fc23..b5084c41884 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -92,7 +92,8 @@ typedef struct bNodeSocket { #define SOCK_IN_USE 4 /* unavailable is for dynamic sockets */ #define SOCK_UNAVAIL 8 - + /* flag for selection status */ +#define SOCK_SEL 16 # # typedef struct bNodePreview { @@ -167,6 +168,10 @@ typedef struct bNodeTree { ListBase alltypes; /* type definitions */ struct bNodeType *owntype; /* for groups or dynamic trees, no read/write */ + /* selected input/output socket */ + bNodeSocket *selin; + bNodeSocket *selout; + /* callbacks */ void (*timecursor)(int nr); void (*stats_draw)(char *str); diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index b0c55d104f3..cc65b10c8e7 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -1988,7 +1988,8 @@ static void draw_nodespace_back(ScrArea *sa, SpaceNode *snode) } /* nice AA filled circle */ -static void socket_circle_draw(float x, float y, float size, int type, int select) +/* this might have some more generic use */ +static void circle_draw(float x, float y, float size, int type, int col[3]) { /* 16 values of sin function */ static float si[16] = { @@ -2006,28 +2007,7 @@ static void socket_circle_draw(float x, float y, float size, int type, int selec }; int a; - if(select==0) { - if(type==-1) - glColor3ub(0, 0, 0); - else if(type==SOCK_VALUE) - glColor3ub(160, 160, 160); - else if(type==SOCK_VECTOR) - glColor3ub(100, 100, 200); - else if(type==SOCK_RGBA) - glColor3ub(200, 200, 40); - else - glColor3ub(100, 200, 100); - } - else { - if(type==SOCK_VALUE) - glColor3ub(200, 200, 200); - else if(type==SOCK_VECTOR) - glColor3ub(140, 140, 240); - else if(type==SOCK_RGBA) - glColor3ub(240, 240, 100); - else - glColor3ub(140, 240, 140); - } + glColor3ub(col[0], col[1], col[2]); glBegin(GL_POLYGON); for(a=0; a<16; a++) @@ -2045,6 +2025,41 @@ static void socket_circle_draw(float x, float y, float size, int type, int selec glDisable(GL_BLEND); } +static void socket_circle_draw(bNodeSocket *sock, float size) +{ + int col[3]; + + /* choose color based on sock flags */ + if(sock->flag & SELECT) { + if(sock->flag & SOCK_SEL) { + col[0]= 240; col[1]= 200; col[2]= 40;} + else if(sock->type==SOCK_VALUE) { + col[0]= 200; col[1]= 200; col[2]= 200;} + else if(sock->type==SOCK_VECTOR) { + col[0]= 140; col[1]= 140; col[2]= 240;} + else if(sock->type==SOCK_RGBA) { + col[0]= 240; col[1]= 240; col[2]= 100;} + else { + col[0]= 140; col[1]= 240; col[2]= 140;} + } + else if(sock->flag & SOCK_SEL) { + col[0]= 200; col[1]= 160; col[2]= 0;} + else { + if(sock->type==-1) { + col[0]= 0; col[1]= 0; col[2]= 0;} + else if(sock->type==SOCK_VALUE) { + col[0]= 160; col[1]= 160; col[2]= 160;} + else if(sock->type==SOCK_VECTOR) { + col[0]= 100; col[1]= 100; col[2]= 200;} + else if(sock->type==SOCK_RGBA) { + col[0]= 200; col[1]= 200; col[2]= 40;} + else { + col[0]= 100; col[1]= 200; col[2]= 100;} + } + + circle_draw(sock->locx, sock->locy, size, sock->type, col); +} + /* not a callback */ static void node_draw_preview(bNodePreview *preview, rctf *prv) { @@ -2459,7 +2474,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node) /* socket inputs, buttons */ for(sock= node->inputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + socket_circle_draw(sock, NODE_SOCKSIZE); if(block && sock->link==NULL) { float *butpoin= sock->ns.vec; @@ -2501,7 +2516,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node) /* socket outputs */ for(sock= node->outputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + socket_circle_draw(sock, NODE_SOCKSIZE); BIF_ThemeColor(TH_TEXT); ofs= 0; @@ -2589,12 +2604,12 @@ void node_draw_hidden(SpaceNode *snode, bNode *node) /* sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + socket_circle_draw(sock, NODE_SOCKSIZE); } for(sock= node->outputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + socket_circle_draw(sock, NODE_SOCKSIZE); } } @@ -2805,10 +2820,10 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode) /* group sockets */ for(sock= gnode->inputs.first; sock; sock= sock->next) if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + socket_circle_draw(sock, NODE_SOCKSIZE); for(sock= gnode->outputs.first; sock; sock= sock->next) if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + socket_circle_draw(sock, NODE_SOCKSIZE); /* and finally the whole tree */ node_draw_nodetree(sa, snode, ngroup); diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index a14b0ccc389..d035908994c 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -830,6 +830,23 @@ static void snode_bg_viewmove(SpaceNode *snode) window_set_cursor(win, oldcursor); } +static void reset_sel_socket(SpaceNode *snode, int in_out) +{ + bNode *node; + bNodeSocket *sock; + + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(in_out & SOCK_IN) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL; + } + if(in_out & SOCK_OUT) { + for(sock= node->outputs.first; sock; sock= sock->next) + if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL; + } + } +} + /* checks mouse position, and returns found node/socket */ /* type is SOCK_IN and/or SOCK_OUT */ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out) @@ -1568,6 +1585,33 @@ static void node_insert_convertor(SpaceNode *snode, bNodeLink *link) #endif +static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link) +{ + bNodeLink *tlink; + bNodeSocket *sock; + + if(tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) { + + for(tlink= snode->edittree->links.first; tlink; tlink= tlink->next) { + if(link!=tlink && tlink->tosock==link->tosock) + break; + } + if(tlink) { + /* is there a free input socket with same type? */ + for(sock= tlink->tonode->inputs.first; sock; sock= sock->next) { + if(sock->type==tlink->fromsock->type) + if(nodeCountSocketLinks(snode->edittree, sock) < sock->limit) + break; + } + if(sock) + tlink->tosock= sock; + else { + nodeRemLink(snode->edittree, tlink); + } + } + } +} + /* loop that adds a nodelink, called by function below */ /* in_out = starting socket */ static int node_add_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int in_out) @@ -1638,35 +1682,12 @@ static int node_add_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, nodeRemLink(snode->edittree, link); } else { - bNodeLink *tlink; - /* send changed events for original tonode and new */ if(link->tonode) NodeTagChanged(snode->edittree, link->tonode); /* we might need to remove a link */ - if(in_out==SOCK_OUT) { - if(tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) { - - for(tlink= snode->edittree->links.first; tlink; tlink= tlink->next) { - if(link!=tlink && tlink->tosock==link->tosock) - break; - } - if(tlink) { - /* is there a free input socket with same type? */ - for(tsock= tlink->tonode->inputs.first; tsock; tsock= tsock->next) { - if(tsock->type==tlink->fromsock->type) - if(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) - break; - } - if(tsock) - tlink->tosock= tsock; - else { - nodeRemLink(snode->edittree, tlink); - } - } - } - } + if(in_out==SOCK_OUT) node_remove_extra_links(snode, tsock, link); } ntreeSolveOrder(snode->edittree); @@ -1733,10 +1754,18 @@ static int node_add_link(SpaceNode *snode) void node_delete(SpaceNode *snode) { bNode *node, *next; + bNodeSocket *sock; for(node= snode->edittree->nodes.first; node; node= next) { next= node->next; if(node->flag & SELECT) { + /* set selin and selout NULL if the sockets belong to a node to be deleted */ + for(sock= node->inputs.first; sock; sock= sock->next) + if(snode->edittree->selin == sock) snode->edittree->selin= NULL; + + for(sock= node->outputs.first; sock; sock= sock->next) + if(snode->edittree->selout == sock) snode->edittree->selout= NULL; + /* check id user here, nodeFreeNode is called for free dbase too */ if(node->id) node->id->us--; @@ -1826,6 +1855,36 @@ void node_select_linked(SpaceNode *snode, int out) allqueue(REDRAWNODE, 1); } +void node_toggle_link(SpaceNode *snode) +{ + bNode *fromnode, *tonode; + bNodeLink *remlink, *link; + bNodeSocket *outsock= snode->edittree->selout; + bNodeSocket *insock= snode->edittree->selin; + + if(!insock || !outsock) return; + + remlink= nodeFindLink(snode->edittree, outsock, insock); + + if(remlink) nodeRemLink(snode->edittree, remlink); + else { + if(nodeFindNode(snode->edittree, outsock, &fromnode, NULL) && + nodeFindNode(snode->edittree, insock, &tonode, NULL)) { + link= nodeAddLink(snode->edittree, fromnode, outsock, tonode, insock); + NodeTagChanged(snode->edittree, tonode); + node_remove_extra_links(snode, insock, link); + } + else return; + } + + ntreeSolveOrder(snode->edittree); + snode_verify_groups(snode); + snode_handle_recalc(snode); + + allqueue(REDRAWNODE, 0); + BIF_undo_push("Toggle Link"); +} + static void node_border_link_delete(SpaceNode *snode) { rcti rect; @@ -2091,6 +2150,8 @@ static int node_uiDoBlocks(ScrArea *sa, short event) void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) { SpaceNode *snode= spacedata; + bNode *actnode; + bNodeSocket *actsock; unsigned short event= evt->event; short val= evt->val, doredraw=0, fromlib= 0; @@ -2118,7 +2179,29 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case RIGHTMOUSE: - if(!node_mouse_select(snode, event)) + if(find_indicated_socket(snode, &actnode, &actsock, SOCK_IN)) { + if(actsock->flag & SOCK_SEL) { + snode->edittree->selin= NULL; + actsock->flag&= ~SOCK_SEL; + } + else { + snode->edittree->selin= actsock; + reset_sel_socket(snode, SOCK_IN); + actsock->flag|= SOCK_SEL; + } + } + else if(find_indicated_socket(snode, &actnode, &actsock, SOCK_OUT)) { + if(actsock->flag & SOCK_SEL) { + snode->edittree->selout= NULL; + actsock->flag&= ~SOCK_SEL; + } + else { + snode->edittree->selout= actsock; + reset_sel_socket(snode, SOCK_OUT); + actsock->flag|= SOCK_SEL; + } + } + else if(!node_mouse_select(snode, event)) toolbox_n(); break; @@ -2194,6 +2277,9 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) case EKEY: snode_handle_recalc(snode); break; + case FKEY: + node_toggle_link(snode); + break; case GKEY: if(fromlib) fromlib= -1; else { diff --git a/source/blender/src/header_node.c b/source/blender/src/header_node.c index ebdd42690f5..7255dcd3286 100644 --- a/source/blender/src/header_node.c +++ b/source/blender/src/header_node.c @@ -513,6 +513,9 @@ static void do_node_nodemenu(void *arg, int event) case 10: /* execute */ addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); break; + case 11: /* toggle link */ + node_toggle_link(snode); + break; } if(fromlib==-1) error_libdata(); @@ -536,6 +539,10 @@ static uiBlock *node_nodemenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Toggle Link|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 969b9d4657b..244e1ffd7c3 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -1648,6 +1648,8 @@ static TBitem tb_node_node[]= { { 0, "Duplicate|Shift D", TB_SHIFT|'d', NULL}, { 0, "Delete|X", 'x', NULL}, { 0, "SEPR", 0, NULL}, + { 0, "Toggle Link|F", 'f', NULL}, + { 0, "SEPR", 0, NULL}, { 0, "Make Group|Ctrl G", TB_CTRL|'g', NULL}, { 0, "Ungroup|Alt G", TB_ALT|'g', NULL}, { 0, "Edit Group|Tab", TB_TAB, NULL}, From c020b9b14666d1648a0bf79276ae8420c532ac14 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 27 Dec 2007 11:20:37 +0000 Subject: [PATCH 65/99] == PoseLib - Bugfixes == * Fixed crash using Interactive Preview, on an armature without a PoseLib * Cancelling Interactive Preview now correctly restores the original Pose * Interactive Preview now sets the correct active pose after it is run * Interactive Preview now also updates the buttons window after it is run * Clicking on the "New PoseLib" button now creates a new PoseLib action, even when one existed before * Poses can be applied using the Pose browsing menu (i.e. when a menu item from that list is clicked, that pose is assigned) --- source/blender/include/BIF_poselib.h | 4 +- source/blender/include/butspace.h | 10 +- source/blender/src/buttons_editing.c | 7 +- source/blender/src/header_view3d.c | 2 +- source/blender/src/poselib.c | 169 ++++++++++++++++++--------- source/blender/src/space.c | 2 +- 6 files changed, 130 insertions(+), 64 deletions(-) diff --git a/source/blender/include/BIF_poselib.h b/source/blender/include/BIF_poselib.h index 2d5978e422e..39997930569 100644 --- a/source/blender/include/BIF_poselib.h +++ b/source/blender/include/BIF_poselib.h @@ -43,12 +43,14 @@ void poselib_unique_pose_name(struct bPoseLib *pl, char name[]); int poselib_get_free_index(struct bPoseLib *pl); struct bPoseLib *poselib_init_new(struct Object *ob); +struct bPoseLib *poselib_validate(struct Object *ob); + void poselib_validate_act(struct bAction *act); void poselib_remove_pose(struct Object *ob, struct bPoseLibRef *plr); void poselib_rename_pose(struct Object *ob); void poselib_add_current_pose(struct Object *ob, int mode); -void poselib_preview_poses(struct Object *ob); +void poselib_preview_poses(struct Object *ob, short apply_active); #endif diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 052da648770..f3058ceb6e6 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -512,10 +512,12 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_ARM_CLEARPATHS 2304 #define B_POSELIB_NEW 2310 -#define B_POSELIB_ADDPOSE 2311 -#define B_POSELIB_REPLACEP 2312 -#define B_POSELIB_REMOVEP 2313 -#define B_POSELIB_VALIDATE 2314 +#define B_POSELIB_VALIDATE 2311 +#define B_POSELIB_ADDPOSE 2312 +#define B_POSELIB_REPLACEP 2313 +#define B_POSELIB_REMOVEP 2314 +#define B_POSELIB_APPLYP 2315 + /* *********************** */ #define B_CAMBUTS 2500 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 3e50b9c5ba9..c3ff9030093 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3765,6 +3765,11 @@ void do_armbuts(unsigned short event) } allqueue(REDRAWBUTSEDIT, 0); break; + case B_POSELIB_APPLYP: + if (ob && ob->pose) + poselib_preview_poses(ob, 1); + allqueue(REDRAWBUTSEDIT, 0); + break; } } @@ -5007,7 +5012,7 @@ static void editing_panel_links(Object *ob) uiBlockBeginAlign(block); /* currently 'active' pose */ - uiDefButI(block, MENU, REDRAWBUTSEDIT, menustr, xco, 85,18,20, &pl->active_nr, 1, plr_count, 0, 0, "Browses Poses in PoseLib"); + uiDefButI(block, MENU, B_POSELIB_APPLYP, menustr, xco, 85,18,20, &pl->active_nr, 1, plr_count, 0, 0, "Browses Poses in PoseLib. Applies chosen pose."); MEM_freeN(menustr); if (pl->active_nr) { diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 55740861998..4006fd803af 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -4055,7 +4055,7 @@ static void do_view3d_pose_armature_poselibmenu(void *arg, int event) switch(event) { case 1: - poselib_preview_poses(ob); + poselib_preview_poses(ob, 0); break; case 2: poselib_add_current_pose(ob, 0); diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index af59f6c55c4..b87a5ea6e97 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -210,7 +210,7 @@ int poselib_get_free_index (bPoseLib *pl) /* ************************************************************* */ -/* Initialise a new poselib */ +/* Initialise a new poselib (whether it is needed or not) */ bPoseLib *poselib_init_new (Object *ob) { bPose *pose= (ob) ? ob->pose : NULL; @@ -220,9 +220,10 @@ bPoseLib *poselib_init_new (Object *ob) if (ELEM(NULL, ob, pose)) return NULL; - /* init pose's poselib action */ - if (pose->poselib == NULL) - pose->poselib= add_empty_action("PoseLib"); + /* init pose's poselib action (unlink old one if there) */ + if (pose->poselib) + pose->poselib->id.us--; + pose->poselib= add_empty_action("PoseLib"); act= pose->poselib; /* init actions's poselib data */ @@ -233,6 +234,22 @@ bPoseLib *poselib_init_new (Object *ob) return pl; } +/* Initialise a new poselib (checks if that needs to happen) */ +bPoseLib *poselib_validate (Object *ob) +{ + bPose *pose= (ob) ? ob->pose : NULL; + bAction *act= (pose) ? pose->poselib : NULL; + bPoseLib *pl= (act) ? act->poselib : NULL; + + if (ELEM(NULL, ob, pose)) + return NULL; + + if (ELEM(NULL, act, pl)) + return poselib_init_new(ob); + else + return pl; +} + /* This tool automagically generates/validates poselib data so that it corresponds to the data * in the action. This is for use in making existing actions usable as poselibs. @@ -384,7 +401,7 @@ void poselib_add_current_pose (Object *ob, int val) return; /* get/initialise poselib */ - pl= poselib_init_new(ob); + pl= poselib_validate(ob); act= pose->poselib; /* validate name and get frame */ @@ -469,7 +486,9 @@ void poselib_remove_pose (Object *ob, bPoseLibRef *plr) if (plr == NULL) return; } else { - // TODO: we should really check if pose occurs in this poselib + /* only continue if pose belongs to poselib */ + if (BLI_findindex(&pl->poses, plr) == -1) + return; } /* remove relevant keyframes */ @@ -554,11 +573,13 @@ void poselib_rename_pose (Object *ob) typedef struct tPoseLib_Backup { struct tPoseLib_Backup *next, *prev; + bPoseChannel *pchan; + float oldloc[3]; float oldsize[3]; float oldquat[4]; - float *loc, *size, *quat; + int oldflag; } tPoseLib_Backup; /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ @@ -583,9 +604,7 @@ static void poselib_backup_posecopy (ListBase *backups, bPose *pose) VECCOPY(plb->oldsize, pchan->size); QUATCOPY(plb->oldquat, pchan->quat); - plb->loc= pchan->loc; - plb->size= pchan->size; - plb->quat= pchan->quat; + plb->pchan= pchan; BLI_addtail(backups, plb); } @@ -598,9 +617,11 @@ static void poselib_backup_restore (ListBase *backups) tPoseLib_Backup *plb; for (plb= backups->first; plb; plb= plb->next) { - VECCOPY(plb->loc, plb->oldloc); - VECCOPY(plb->size, plb->oldsize); - VECCOPY(plb->quat, plb->oldquat); + VECCOPY(plb->pchan->loc, plb->oldloc); + VECCOPY(plb->pchan->size, plb->oldsize); + VECCOPY(plb->pchan->quat, plb->oldquat); + + plb->pchan->flag = plb->oldflag; } } @@ -718,7 +739,8 @@ static void poselib_keytag_pose (Object *ob) enum { PL_PREVIEW_RUNNING = 0, PL_PREVIEW_CONFIRM, - PL_PREVIEW_CANCEL + PL_PREVIEW_CANCEL, + PL_PREVIEW_RUNONCE }; /* defines for poselib_preview_poses --> redraw values */ @@ -728,8 +750,10 @@ enum { PL_PREVIEW_REDRAWHEADER, }; -/* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown */ -void poselib_preview_poses (Object *ob) +/* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown + * It is also used to apply the active poselib pose only + */ +void poselib_preview_poses (Object *ob, short apply_active) { ListBase backups = {NULL, NULL}; @@ -737,9 +761,11 @@ void poselib_preview_poses (Object *ob) bArmature *arm= (ob) ? (ob->data) : NULL; bAction *act= (pose) ? (pose->poselib) : NULL; bPoseLib *pl= (act) ? (act->poselib) : NULL; - bPoseLibRef *plr= (pl->active_nr) ? BLI_findlink(&pl->poses, pl->active_nr-1) : pl->poses.first; + bPoseLibRef *plr= (pl == NULL) ? NULL : (pl->active_nr) ? BLI_findlink(&pl->poses, pl->active_nr-1) : pl->poses.first; + Base *base; - short ret_val=PL_PREVIEW_RUNNING, val=0, redraw=1, firsttime=1; + short ret_val= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING; + short val=0, redraw=1, firsttime=1; unsigned short event; char headerstr[200]; @@ -767,7 +793,7 @@ void poselib_preview_poses (Object *ob) /* start preview loop */ - while (ret_val == PL_PREVIEW_RUNNING) { + while (ELEM(ret_val, PL_PREVIEW_RUNNING, PL_PREVIEW_RUNONCE)) { /* preview a pose */ if (redraw) { /* only recalc pose (and its dependencies) if pose has changed */ @@ -785,8 +811,6 @@ void poselib_preview_poses (Object *ob) * - note: code copied from transform_generics.c -> recalcData() */ if ((arm->flag & ARM_DELAYDEFORM)==0) { - Base *base; - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ /* bah, softbody exception... recalcdata doesnt reset */ @@ -801,17 +825,26 @@ void poselib_preview_poses (Object *ob) where_is_pose(ob); } - /* do header print */ - sprintf(headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", plr->name); - headerprint(headerstr); + /* do header print - if interactively previewing */ + if (ret_val == PL_PREVIEW_RUNNING) { + sprintf(headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", plr->name); + headerprint(headerstr); + } /* force drawing of view + clear redraw flag */ force_draw(0); redraw= PL_PREVIEW_NOREDRAW; } + /* stop now if only running once */ + if (ret_val == PL_PREVIEW_RUNONCE) { + ret_val = PL_PREVIEW_CONFIRM; + break; + } + /* essential for idling subloop */ - if (qtest() == 0) PIL_sleep_ms(2); + if (qtest() == 0) + PIL_sleep_ms(2); /* emptying queue and reading events */ while ( qtest() ) { @@ -832,7 +865,7 @@ void poselib_preview_poses (Object *ob) case SPACEKEY: ret_val= PL_PREVIEW_CONFIRM; break; - + /* change to previous pose - go back to end of list if no previous (cyclic) */ case PAGEUPKEY: case WHEELUPMOUSE: @@ -867,39 +900,63 @@ void poselib_preview_poses (Object *ob) } } - /* clear pose if cancelled */ - if (ret_val == PL_PREVIEW_CANCEL) { - poselib_backup_restore(&backups); - where_is_pose(ob); - } - BLI_freelistN(&backups); - - /* auto-keying if not cancelled */ - if (ret_val == PL_PREVIEW_CONFIRM) - poselib_keytag_pose(ob); - /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */ pose->flag |= POSE_DO_UNLOCK; - /* Update event for pose and deformation children */ - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + /* clear pose if cancelled */ + if (ret_val == PL_PREVIEW_CANCEL) { + poselib_backup_restore(&backups); + + /* old optimize trick... this enforces to bypass the depgraph + * - note: code copied from transform_generics.c -> recalcData() + */ + if ((arm->flag & ARM_DELAYDEFORM)==0) { + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + + /* bah, softbody exception... recalcdata doesnt reset */ + for (base= FIRSTBASE; base; base= base->next) { + if (base->object->recalc & OB_RECALC_DATA) + if (modifiers_isSoftbodyEnabled(base->object)) { + base->object->softflag |= OB_SB_REDO; + } + } + } + else + where_is_pose(ob); + + allqueue(REDRAWVIEW3D, 0); + } + else if (ret_val == PL_PREVIEW_CONFIRM) { + /* tag poses as appropriate */ + poselib_keytag_pose(ob); + + /* change active pose setting */ + pl->active_nr= BLI_findindex(&pl->poses, plr) + 1; + + /* Update event for pose and deformation children */ + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + + /* updates */ + if (G.flags & G_RECORDKEYS) { + remake_action_ipos(ob->action); + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + else { + /* need to trick depgraph, action is not allowed to execute on pose */ + where_is_pose(ob); + ob->recalc= 0; + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + } + } + /* free memory used for backups */ + BLI_freelistN(&backups); - /* updates */ - if (G.flags & G_RECORDKEYS) { - remake_action_ipos(ob->action); - - allqueue(REDRAWIPO, 0); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWACTION, 0); - allqueue(REDRAWNLA, 0); - } - else { - /* need to trick depgraph, action is not allowed to execute on pose */ - where_is_pose(ob); - ob->recalc= 0; - - allqueue(REDRAWVIEW3D, 0); - } - BIF_undo_push("PoseLib Apply Pose"); } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index ca0ee8f90ca..5862eebc8a8 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2135,7 +2135,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else if(ob && (ob->flag & OB_POSEMODE)) { if (G.qual == LR_CTRLKEY) - poselib_preview_poses(ob); + poselib_preview_poses(ob, 0); else if (G.qual == LR_SHIFTKEY) poselib_add_current_pose(ob, 0); else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) From 28805c626fffdc70736e26dccb2ef37816c4bc76 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Dec 2007 13:35:14 +0000 Subject: [PATCH 66/99] ==Python API== added mipmap as an option for Blender.Get/Set --- source/blender/python/api2_2x/Blender.c | 25 +++++++++++++++----- source/blender/python/api2_2x/doc/Blender.py | 2 ++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 05eb82802b8..2bcc9d21da4 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -1,5 +1,5 @@ /* - * $Id: Blender.c 12702 2007-11-27 23:15:51Z campbellbarton $ + * $Id$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -285,11 +285,23 @@ static PyObject *Blender_Set( PyObject * self, PyObject * args ) return EXPP_ReturnPyObjError( PyExc_ValueError, "expected an integer" ); - if (value) - U.flag |= USER_FILECOMPRESS; + if (value) + U.flag |= USER_FILECOMPRESS; else - U.flag &= ~USER_FILECOMPRESS; + U.flag &= ~USER_FILECOMPRESS; + } else if (StringEqual( name , "mipmap" ) ) { + int value = PyObject_IsTrue( arg ); + if (value==-1) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "expected an integer" ); + + if (value) + U.gameflags &= ~USER_DISABLE_MIPMAP; + else + U.gameflags |= USER_DISABLE_MIPMAP; + + set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); }else return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "value given is not a blender setting" ) ); @@ -521,14 +533,15 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value ) else if(StringEqual( str, "compressfile" )) ret = PyInt_FromLong( (U.flag & USER_FILECOMPRESS) >> 15 ); - + else if(StringEqual( str, "mipmap" )) + ret = PyInt_FromLong( (U.gameflags & USER_DISABLE_MIPMAP) == 0 ); else return EXPP_ReturnPyObjError( PyExc_AttributeError, "unknown attribute" ); if (ret) return ret; else return EXPP_ReturnPyObjError (PyExc_MemoryError, - "could not create pystring!"); + "could not create the PyObject!"); } /*****************************************************************************/ diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py index 088a02c547c..9e994bfbe64 100644 --- a/source/blender/python/api2_2x/doc/Blender.py +++ b/source/blender/python/api2_2x/doc/Blender.py @@ -69,6 +69,7 @@ def Set (request, data): - 'renderdir': default render output dir - 'soundsdir': sound dir - 'tempdir': temp file storage dir + - 'mipmap' : Use mipmapping in the 3d view (Use a boolean value True/False). @type data: int or string @param data: The new value. """ @@ -106,6 +107,7 @@ def Get (request): - 'soundsdir': the path to the user defined dir for sound files. (*) - 'tempdir': the path to the user defined dir for storage of Blender temporary files. (*) + - 'mipmap' : Use mipmapping in the 3d view. (*) - 'version' : the Blender version number. @note: (*) these can be set in Blender at the User Preferences window -> File Paths tab. From 8ddc48d32f011b0c5af5c191a94188e3f29c3776 Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Thu, 27 Dec 2007 14:19:11 +0000 Subject: [PATCH 67/99] Directional Blur Node Directional Blur node allows the users to do various blur operations on the input image. It essentially offers three different kind of ways of blurring in one node. It is possible to blur using a certain direction, spin and zoom. These three ways can be used in conjunction. The node contains following controls: *Iterations, Wrap *Center: X, Y *Distance, Angle *Spin *Zoom Iterations is used to determine the smoothness of the result. The more iterations, the smoother result. Low values are good for preview. Wrap means that the image is wrapped as if it was tiled on both x and y directions. To see better what this means, try it with spin for instance. Center values (X and Y) determine the location which is used as a pivot point for the operations. It is center (0.5) of the image by default. Distance and angle are used to adjust directional blur. The result can be described as a sweep that varies based on given distance (bigger distance, longer sweep) and angle. Angle is given in degrees. Spin produces rotating blur based on given angle. Yet again it is in degrees. Also negative values work. Zoom causes the image to be zoomed towards set center point (Center values). Thanks to Alfredo de Greef (eeshlo) for contribution. Possible development ideas: *Make an algorithm to extend image in case spin is used. Extend would temporarily change the size of the canvas of the input image. Canvas would be filled based on colors on the edges of the input image. After the blur operation has been done, the image would be cropped back to normal size. The advantage of this would be nicer result of spin (no problems with image size) on a computational cost. *Make values animatable. This is something that is better solved on more general level. ("everything is animatable" paradigm) *Provide an option to calculate automatic value for iterations. A good value that produces a smooth result could be calculated based on direction deltas. This would be useful in conjuction of animatable values. --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/BKE_utildefines.h | 2 + source/blender/blenkernel/intern/node.c | 1 + source/blender/makesdna/DNA_node_types.h | 6 + source/blender/nodes/CMP_node.h | 1 + .../intern/CMP_nodes/CMP_directionalblur.c | 143 ++++++++++++++++++ source/blender/src/drawnode.c | 69 ++++++++- 7 files changed, 218 insertions(+), 5 deletions(-) create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b9df1e45bae..3fd9d00b208 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -306,6 +306,7 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str #define CMP_NODE_INVERT 251 #define CMP_NODE_NORMALIZE 252 #define CMP_NODE_CROP 253 +#define CMP_NODE_DBLUR 254 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index f3f66190c31..d08f42375ac 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -101,6 +101,8 @@ #define ABS(a) ( (a)<0 ? (-(a)) : (a) ) +#define AVG2(x, y) ( 0.5 * ((x) + (y)) ) + #define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);} #define VECCOPY2D(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1);} #define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);} diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 4bcacae9fc5..9450b4353cf 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2374,6 +2374,7 @@ static void registerCompositNodes(ListBase *ntypelist) nodeRegisterType(ntypelist, &cmp_node_filter); nodeRegisterType(ntypelist, &cmp_node_blur); + nodeRegisterType(ntypelist, &cmp_node_dblur); nodeRegisterType(ntypelist, &cmp_node_vecblur); nodeRegisterType(ntypelist, &cmp_node_dilateerode); nodeRegisterType(ntypelist, &cmp_node_defocus); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b5084c41884..e010d8409fa 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -203,6 +203,12 @@ typedef struct NodeBlurData { int pad2; } NodeBlurData; +typedef struct NodeDBlurData { + float center_x, center_y, distance, angle, spin, zoom; + short iter; + char wrap, pad; +} NodeDBlurData; + typedef struct NodeHueSat { float hue, sat, val; } NodeHueSat; diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h index 4b7e721ca57..d1e04065835 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -66,6 +66,7 @@ extern bNodeType cmp_node_normalize; extern bNodeType cmp_node_filter; extern bNodeType cmp_node_blur; +extern bNodeType cmp_node_dblur; extern bNodeType cmp_node_vecblur; extern bNodeType cmp_node_dilateerode; extern bNodeType cmp_node_defocus; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c new file mode 100644 index 00000000000..27f535186db --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c @@ -0,0 +1,143 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Alfredo de Greef (eeshlo) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../CMP_util.h" + +static bNodeSocketType cmp_node_dblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f, 0.f, 1.f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_dblur_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap, + float center_x, float center_y, float dist, float angle, float spin, float zoom) +{ + if ((dist != 0.f) || (spin != 0.f) || (zoom != 0.f)) { + void (*getpix)(CompBuf*, float, float, float*) = wrap ? qd_getPixelLerpWrap : qd_getPixelLerp; + const float a= angle * (float)M_PI / 180.f; + const float itsc= 1.f / pow(2.f, (float)iterations); + float D; + float center_x_pix, center_y_pix; + float tx, ty; + float sc, rot; + CompBuf *tmp; + int i, j; + + tmp= dupalloc_compbuf(img); + + D= dist * sqrtf(img->x * img->x + img->y * img->y); + center_x_pix= center_x * img->x; + center_y_pix= center_y * img->y; + + tx= itsc * D * cos(a); + ty= -itsc * D * sin(a); + sc= itsc * zoom; + rot= itsc * spin * (float)M_PI / 180.f; + + /* blur the image */ + for(i= 0; i < iterations; ++i) { + const float cs= cos(rot), ss= sin(rot); + const float isc= 1.f / (1.f + sc); + unsigned int x, y; + float col[4]= {0,0,0,0}; + + for(y= 0; y < img->y; ++y) { + const float v= isc * (y - center_y_pix) + ty; + + for(x= 0; x < img->x; ++x) { + const float u= isc * (x - center_x_pix) + tx; + unsigned int p= (x + y * img->x) * img->type; + + getpix(tmp, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, col); + + /* mix img and transformed tmp */ + for(j= 0; j < 4; ++j) + img->rect[p + j]= AVG2(img->rect[p + j], col[j]); + } + } + + /* copy img to tmp */ + if(i != (iterations - 1)) + memcpy(tmp->rect, img->rect, sizeof(float) * img->x * img->y * img->type); + + /* double transformations */ + tx *= 2.f, ty *= 2.f; + sc *= 2.f, rot *= 2.f; + + if(node->exec & NODE_BREAK) break; + } + + free_compbuf(tmp); + } + + return img; +} + +static void node_composit_exec_dblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + NodeDBlurData *ndbd= node->storage; + CompBuf *new, *img= in[0]->data; + + if((img == NULL) || (out[0]->hasoutput == 0)) return; + + if (img->type != CB_RGBA) + new = typecheck_compbuf(img, CB_RGBA); + else + new = dupalloc_compbuf(img); + + out[0]->data= dblur(node, new, ndbd->iter, ndbd->wrap, ndbd->center_x, ndbd->center_y, ndbd->distance, ndbd->angle, ndbd->spin, ndbd->zoom); +} + +static void node_composit_init_dblur(bNode* node) +{ + NodeDBlurData *ndbd= MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); + node->storage= ndbd; + ndbd->center_x= 0.5; + ndbd->center_y= 0.5; +} + +bNodeType cmp_node_dblur = { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_DBLUR, + /* name */ "Directional Blur", + /* width+range */ 150, 120, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_dblur_in, + /* output sock */ cmp_node_dblur_out, + /* storage */ "NodeDBlurData", + /* execfunc */ node_composit_exec_dblur, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_dblur, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL +}; diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index cc65b10c8e7..f641efacdbd 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -1085,6 +1085,63 @@ static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node return 57; } +static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeDBlurData *ndbd = node->storage; + short dy = butr->ymin + 171; + short dx = butr->xmax - butr->xmin; + short halfdx= (short)dx/2; + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Iterations:", + butr->xmin, dy, dx, 19, + &ndbd->iter, 1, 32, 10, 0, "Amount of iterations"); + uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "Wrap", + butr->xmin, dy-= 19, dx, 19, + &ndbd->wrap, 0, 0, 0, 0, "Wrap blur"); + uiBlockEndAlign(block); + + dy-= 9; + + uiDefBut(block, LABEL, B_NOP, "Center", butr->xmin, dy-= 19, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "X:", + butr->xmin, dy-= 19, halfdx, 19, + &ndbd->center_x, 0.0f, 1.0f, 10, 0, "X center in percents"); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Y:", + butr->xmin+halfdx, dy, halfdx, 19, + &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents"); + uiBlockEndAlign(block); + + dy-= 9; + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Distance:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->distance, -1.0f, 1.0f, 10, 0, "Amount of which the image moves"); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Angle:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->angle, 0.0f, 360.0f, 1000, 0, "Angle in which the image will be moved"); + uiBlockEndAlign(block); + + dy-= 9; + + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Spin:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image"); + + dy-= 9; + + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Zoom:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed"); + + } + return 190; +} + /* qdn: defocus node */ static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { @@ -1334,7 +1391,6 @@ static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node { if(block) { NodeTwoXYs *ntxy= node->storage; - uiBut *bt; char elementheight = 19; short dx= (butr->xmax-butr->xmin)/2; short dy= butr->ymax - elementheight; @@ -1350,22 +1406,22 @@ static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node dy-=elementheight; /* x1 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X1:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X1:", butr->xmin, dy, dx, elementheight, &ntxy->x1, xymin, xymax, 0, 0, ""); /* y1 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y1:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y1:", butr->xmin+dx, dy, dx, elementheight, &ntxy->y1, xymin, xymax, 0, 0, ""); dy-=elementheight; /* x2 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X2:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X2:", butr->xmin, dy, dx, elementheight, &ntxy->x2, xymin, xymax, 0, 0, ""); /* y2 */ - bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y2:", + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y2:", butr->xmin+dx, dy, dx, elementheight, &ntxy->y2, xymin, xymax, 0, 0, ""); @@ -1808,6 +1864,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_BLUR: ntype->butfunc= node_composit_buts_blur; break; + case CMP_NODE_DBLUR: + ntype->butfunc= node_composit_buts_dblur; + break; /* qdn: defocus node */ case CMP_NODE_DEFOCUS: ntype->butfunc = node_composit_buts_defocus; From 59d40d7f84c5d4f7536fe9642f26f1e5483a68a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Dec 2007 20:33:29 +0000 Subject: [PATCH 68/99] DupliGroups can now instance duplifaces and duplierts - not nice code, but this should help a move to proper recursive dupli's. This is needed for peach project leaves on tree's (space.c better tooltip for mipmaps) --- source/blender/blenkernel/intern/anim.c | 176 +++++++++++++++++++----- source/blender/src/space.c | 2 +- 2 files changed, 141 insertions(+), 37 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1eb7e232382..3a3e55aedeb 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -74,6 +74,9 @@ #include #endif +static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]); +static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]); + void free_path(Path *path) { if(path->data) MEM_freeN(path->data); @@ -315,14 +318,49 @@ static void group_duplilist(ListBase *lb, Object *ob, int level) for(go= group->gobject.first; go; go= go->next) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ if(go->ob!=ob) { + Mat4MulMat4(mat, go->ob->obmat, ob->obmat); dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0); dob->no_draw= (dob->origlay & group->layer)==0; - if(go->ob->dup_group && (go->ob->transflag & OB_DUPLIGROUP)) { - Mat4CpyMat4(dob->ob->obmat, dob->mat); - group_duplilist(lb, go->ob, level+1); - Mat4CpyMat4(dob->ob->obmat, dob->omat); + /* TODO - This code replicates object_duplilist, should be merged - Campbell */ + if(go->ob->transflag & OB_DUPLI) { + if(go->ob->transflag & OB_DUPLIPARTS) { + /* TODO - keep so if's stay the same */ + /* + ParticleSystem *psys = ob->particlesystem.first; + for(; psys; psys=psys->next) + new_particle_duplilist(duplilist, sce, ob, psys); + */ + } + else if(go->ob->transflag & OB_DUPLIVERTS) { + if(go->ob->type==OB_MESH) { + Mat4CpyMat4(dob->ob->obmat, dob->mat); + vertex_duplilist(lb, (ID *)group, go->ob, &ob->obmat); + Mat4CpyMat4(dob->ob->obmat, dob->omat); + } + else if(go->ob->type==OB_FONT) { + /* TODO - does anyone use these ? ;) */ + //font_duplilist(duplilist, ob); + } + } + else if(go->ob->transflag & OB_DUPLIFACES) { + if(go->ob->type==OB_MESH) { + Mat4CpyMat4(dob->ob->obmat, dob->mat); + face_duplilist(lb, (ID *)group, go->ob, &ob->obmat); + Mat4CpyMat4(dob->ob->obmat, dob->omat); + } + } + else if(go->ob->transflag & OB_DUPLIFRAMES) { + /* TODO??? - This one is not easy, maybe we should never support it. + frames_duplilist(duplilist, go->ob);*/ + } else if(ob->transflag & OB_DUPLIGROUP) { + if(go->ob->dup_group) { + Mat4CpyMat4(dob->ob->obmat, dob->mat); + group_duplilist(lb, go->ob, level+1); + Mat4CpyMat4(dob->ob->obmat, dob->omat); + } + } } } } @@ -364,6 +402,7 @@ static void frames_duplilist(ListBase *lb, Object *ob) struct vertexDupliData { ListBase *lb; float pmat[4][4]; + float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ Object *ob, *par; }; @@ -375,9 +414,9 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n VECCOPY(vec, co); Mat4MulVecfl(vdd->pmat, vec); VecSubf(vec, vec, vdd->pmat[3]); - VecAddf(vec, vec, vdd->ob->obmat[3]); + VecAddf(vec, vec, vdd->obmat[3]); - Mat4CpyMat4(obmat, vdd->ob->obmat); + Mat4CpyMat4(obmat, vdd->obmat); VECCOPY(obmat[3], vec); if(vdd->par->transflag & OB_DUPLIROT) { @@ -397,18 +436,20 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index); } -static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par) +static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]) { - Object *ob; - Base *base; + Object *ob, *ob_iter; + Base *base = NULL; float vec[3], no[3], pmat[4][4]; - int lay, totvert, a; + int lay, totvert, a, oblay; DerivedMesh *dm; + struct vertexDupliData vdd; + Scene *sce = NULL; + Group *group = NULL; + GroupObject * go = NULL; Mat4CpyMat4(pmat, par->obmat); - lay= G.scene->lay; - if(par==G.obedit) dm= editmesh_get_derived_cage(CD_MASK_BAREMESH); else @@ -416,16 +457,43 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par) totvert = dm->getNumVerts(dm); - base= sce->base.first; - while(base) { - - if(base->object->type>0 && (lay & base->lay) && G.obedit!=base->object) { - ob= base->object->parent; + /* having to loop on scene OR group objects is NOT FUN */ + if (GS(id->name) == ID_SCE) { + sce = (Scene *)id; + lay= sce->lay; + base= sce->base.first; + } else { + group = (Group *)id; + lay= group->layer; + go = group->gobject.first; + } + + /* Start looping on Scene OR Group objects */ + while (base || go) { + if (sce) { + ob_iter= base->object; + oblay = base->lay; + } else { + ob_iter= go->ob; + oblay = ob_iter->lay; + } + + if (ob_iter->type>0 && (lay & oblay) && G.obedit!=ob_iter) { + ob=ob_iter->parent; while(ob) { if(ob==par) { - struct vertexDupliData vdd; + ob = ob_iter; + /* End Scene/Group object loop, below is generic */ + + /* par_space_mat - only used for groups so we can modify the space dupli's are in + when par_space_mat is NULL ob->obmat can be used instead of ob__obmat + */ + if (par_space_mat) { + Mat4MulMat4(vdd.obmat, ob->obmat, *par_space_mat); + } else { + Mat4CpyMat4(vdd.obmat, ob->obmat); + } - ob= base->object; vdd.lb= lb; vdd.ob= ob; vdd.par= par; @@ -451,26 +519,30 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par) ob= ob->parent; } } - base= base->next; + if (sce) base= base->next; /* scene loop */ + else go= go->next; /* group loop */ } dm->release(dm); } -static void face_duplilist(ListBase *lb, Scene *sce, Object *par) +static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]) { - Object *ob; - Base *base; + Object *ob, *ob_iter; + Base *base = NULL; DerivedMesh *dm; MFace *mface; MVert *mvert; float pmat[4][4], imat[3][3]; - int lay, totface, a; + int lay, oblay, totface, a; + Scene *sce = NULL; + Group *group = NULL; + GroupObject *go = NULL; + + float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */ Mat4CpyMat4(pmat, par->obmat); - lay= G.scene->lay; - if(par==G.obedit) { int totvert; dm= editmesh_get_derived_cage(CD_MASK_BAREMESH); @@ -491,16 +563,46 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par) } - for(base= sce->base.first; base; base= base->next) { + /* having to loop on scene OR group objects is NOT FUN */ + if (GS(id->name) == ID_SCE) { + sce = (Scene *)id; + lay= sce->lay; + base= sce->base.first; + } else { + group = (Group *)id; + lay= group->layer; + go = group->gobject.first; + } + + /* Start looping on Scene OR Group objects */ + while (base || go) { + if (sce) { + ob_iter= base->object; + oblay = base->lay; + } else { + ob_iter= go->ob; + oblay = ob_iter->lay; + } - if(base->object->type>0 && (lay & base->lay) && G.obedit!=base->object) { - ob= base->object->parent; + if (ob_iter->type>0 && (lay & oblay) && G.obedit!=ob_iter) { + ob=ob_iter->parent; while(ob) { if(ob==par) { + ob = ob_iter; + /* End Scene/Group object loop, below is generic */ + + + /* par_space_mat - only used for groups so we can modify the space dupli's are in + when par_space_mat is NULL ob->obmat can be used instead of ob__obmat + */ + if (par_space_mat) { + Mat4MulMat4(ob__obmat, ob->obmat, *par_space_mat); + } else { + Mat4CpyMat4(ob__obmat, ob->obmat); + } - ob= base->object; Mat3CpyMat4(imat, ob->parentinv); - + /* mballs have a different dupli handling */ if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ @@ -519,9 +621,10 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par) Mat4MulVecfl(pmat, cent); VecSubf(cent, cent, pmat[3]); - VecAddf(cent, cent, ob->obmat[3]); + VecAddf(cent, cent, ob__obmat[3]); + + Mat4CpyMat4(obmat, ob__obmat); - Mat4CpyMat4(obmat, ob->obmat); VECCOPY(obmat[3], cent); /* rotation */ @@ -542,7 +645,6 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par) Mat4MulMat43(obmat, tmat, mat); new_dupli_object(lb, ob, obmat, lay, a); - } break; @@ -550,6 +652,8 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par) ob= ob->parent; } } + if (sce) base= base->next; /* scene loop */ + else go= go->next; /* group loop */ } if(par==G.obedit) { @@ -784,7 +888,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob) } else if(ob->transflag & OB_DUPLIVERTS) { if(ob->type==OB_MESH) { - vertex_duplilist(duplilist, sce, ob); + vertex_duplilist(duplilist, (ID *)sce, ob, NULL); } else if(ob->type==OB_FONT) { font_duplilist(duplilist, ob); @@ -792,7 +896,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob) } else if(ob->transflag & OB_DUPLIFACES) { if(ob->type==OB_MESH) - face_duplilist(duplilist, sce, ob); + face_duplilist(duplilist, (ID *)sce, ob, NULL); } else if(ob->transflag & OB_DUPLIFRAMES) frames_duplilist(duplilist, ob); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 5862eebc8a8..bfb67b6a07d 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3978,7 +3978,7 @@ void drawinfospace(ScrArea *sa, void *spacedata) uiDefButBitI(block, TOGN, USER_DISABLE_MIPMAP, B_MIPMAPCHANGED, "Mipmaps", (xpos+edgsp+(5*mpref)+(5*midsp)),y5,mpref,buth, - &(U.gameflags), 0, 0, 0, 0, "Toggles between mipmap textures on (beautiful) and off (fast)"); + &(U.gameflags), 0, 0, 0, 0, "Scale textures for the 3d View (Looks nicer but uses more memory and slows image reloading)"); /* main choices pup: note, it uses collums, and the seperators (%l) then have to fill both halves equally for the menu to work */ uiDefButS(block, MENU, B_GLRESLIMITCHANGED, "GL Texture Clamp Off%x0|%l|GL Texture Clamp 8192%x8192|GL Texture Clamp 4096%x4096|GL Texture Clamp 2048%x2048|GL Texture Clamp 1024%x1024|GL Texture Clamp 512%x512|GL Texture Clamp 256%x256|GL Texture Clamp 128%x128", From f4015d9fce21a4aa5991e3977a146183b1ea32ba Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Thu, 27 Dec 2007 20:36:17 +0000 Subject: [PATCH 69/99] Bilateral Blur Node Bilateral Blur node allows the user to blur images while retaining their sharp edges. Blurring can be controlled by following controls: *Iterations *Color Sigma *Space Sigma Also image input to blur and a determinator image is provided. The node produces a blurred image as its output. The more iterations are provided, the smoother the result. Use color and space sigmas to control the amount of blur. One way to use the determinator input is to feed a mix (add) of Z and normal passes to it. Examples of usage: Ambient Occlusion smoothing - http://wiki.blender.org/index.php/Image:Bilateral_blur_example_01.blend Blurry Refraction - http://wiki.blender.org/index.php/Image:Bilateral_blur_example_02.blend Smoothed shadows and smoothed Ambient Occlusion combined - http://wiki.blender.org/index.php/Image:Bilateral_blur_example_03.blend If you check out the examples, render the image and alter the values to see how they affect. More information about the algorithm can be found at http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html . Thanks to Vilem Novak for contributing the patch. --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + source/blender/makesdna/DNA_node_types.h | 5 + source/blender/nodes/CMP_node.h | 1 + .../intern/CMP_nodes/CMP_bilateralblur.c | 273 ++++++++++++++++++ source/blender/src/drawnode.c | 27 ++ 6 files changed, 308 insertions(+) create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 3fd9d00b208..2008b18b5ed 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -307,6 +307,7 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str #define CMP_NODE_NORMALIZE 252 #define CMP_NODE_CROP 253 #define CMP_NODE_DBLUR 254 +#define CMP_NODE_BILATERALBLUR 255 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 9450b4353cf..ce14165a499 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2375,6 +2375,7 @@ static void registerCompositNodes(ListBase *ntypelist) nodeRegisterType(ntypelist, &cmp_node_filter); nodeRegisterType(ntypelist, &cmp_node_blur); nodeRegisterType(ntypelist, &cmp_node_dblur); + nodeRegisterType(ntypelist, &cmp_node_bilateralblur); nodeRegisterType(ntypelist, &cmp_node_vecblur); nodeRegisterType(ntypelist, &cmp_node_dilateerode); nodeRegisterType(ntypelist, &cmp_node_defocus); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index e010d8409fa..ceab9a1c9c1 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -209,6 +209,11 @@ typedef struct NodeDBlurData { char wrap, pad; } NodeDBlurData; +typedef struct NodeBilateralBlurData { + float sigma_color, sigma_space; + short iter, pad; +} NodeBilateralBlurData; + typedef struct NodeHueSat { float hue, sat, val; } NodeHueSat; diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h index d1e04065835..3e62ea9970f 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -67,6 +67,7 @@ extern bNodeType cmp_node_normalize; extern bNodeType cmp_node_filter; extern bNodeType cmp_node_blur; extern bNodeType cmp_node_dblur; +extern bNodeType cmp_node_bilateralblur; extern bNodeType cmp_node_vecblur; extern bNodeType cmp_node_dilateerode; extern bNodeType cmp_node_defocus; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c new file mode 100644 index 00000000000..81592becf4b --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c @@ -0,0 +1,273 @@ +/** + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Vilem Novak + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include "../CMP_util.h" + +/* **************** BILATERALBLUR ******************** */ +static bNodeSocketType cmp_node_bilateralblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_bilateralblur_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +#define INIT_C3\ + mean0 = 1; mean1[0] = src[0];mean1[1] = src[1];mean1[2] = src[2];mean1[3] = src[3]; + +/* finds color distances */ +#define COLOR_DISTANCE_C3(c1, c2)\ + ((c1[0] - c2[0])*(c1[0] - c2[0]) + \ + (c1[1] - c2[1])*(c1[1] - c2[1]) + \ + (c1[2] - c2[2])*(c1[2] - c2[2]) + \ + (c1[3] - c2[3])*(c1[3] - c2[3])) + +/* this is the main kernel function for comparing color distances + and adding them weighted to the final color */ +#define KERNEL_ELEMENT_C3(k)\ + temp_color = src + deltas[k];\ + ref_color = ref + deltas[k];\ + w = weight_tab[k] + COLOR_DISTANCE_C3(ref, ref_color )*i2sigma_color;\ + w = 1./(w*w + 1); \ + mean0 += w;\ + mean1[0] += temp_color[0]*w; \ + mean1[1] += temp_color[1]*w; \ + mean1[2] += temp_color[2]*w; \ + mean1[3] += temp_color[3]*w; + +/* write blurred values to image */ +#define UPDATE_OUTPUT_C3\ + mean0 = 1./mean0;\ + dest[x*pix + 0] = mean1[0]*mean0; \ + dest[x*pix + 1] = mean1[1]*mean0; \ + dest[x*pix + 2] = mean1[2]*mean0; \ + dest[x*pix + 3] = mean1[3]*mean0; + +/* initializes deltas for fast access to neighbour pixels */ +#define INIT_3X3_DELTAS( deltas, step, nch ) \ + ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ + (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ + (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ + (deltas)[6] = (step), (deltas)[7] = (step) + (nch)); + + +/* code of this node was heavily inspired by the smooth function of opencv library. +The main change is an optional image input */ +static void node_composit_exec_bilateralblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + NodeBilateralBlurData *nbbd= node->storage; + CompBuf *new, *source, *img= in[0]->data , *refimg= in[1]->data; + double mean0, w, i2sigma_color, i2sigma_space; + double mean1[4]; + double weight_tab[8]; + float *src, *dest, *ref, *temp_color, *ref_color; + float sigma_color, sigma_space; + int imgx, imgy, x, y, pix, i, step; + int deltas[8]; + short found_determinator= 0; + + if(img == NULL || out[0]->hasoutput == 0) + return; + + if(img->type != CB_RGBA) { + img= typecheck_compbuf(in[0]->data, CB_RGBA); + } + + imgx= img->x; + imgy= img->y; + pix= img->type; + step= pix * imgx; + + if(refimg) { + refimg= img; + if(refimg->x == imgx && refimg->y == imgy) { + if(refimg->type == CB_VEC2 || refimg->type == CB_VEC3) { + refimg= typecheck_compbuf(in[1]->data, CB_RGBA); + found_determinator= 1; + } + } + } + else { + refimg= img; + } + + /* allocs */ + source= dupalloc_compbuf(img); + new= alloc_compbuf(imgx, imgy, pix, 1); + + /* accept image offsets from other nodes */ + new->xof= img->xof; + new->yof= img->yof; + + /* bilateral code properties */ + sigma_color= nbbd->sigma_color; + sigma_space= nbbd->sigma_space; + + i2sigma_color= 1. / (sigma_color * sigma_color); + i2sigma_space= 1. / (sigma_space * sigma_space); + + INIT_3X3_DELTAS(deltas, step, pix); + + weight_tab[0] = weight_tab[2] = weight_tab[4] = weight_tab[6] = i2sigma_space; + weight_tab[1] = weight_tab[3] = weight_tab[5] = weight_tab[7] = i2sigma_space * 2; + + /* iterations */ + for(i= 0; i < nbbd->iter; i++) { + src= source->rect; + ref= refimg->rect; + dest= new->rect; + /*goes through image, there are more loops for 1st/last line and all other lines*/ + /*kernel element accumulates surrounding colors, which are then written with the update_output function*/ + for(x= 0; x < imgx; x++, src+= pix, ref+= pix) { + INIT_C3; + + KERNEL_ELEMENT_C3(6); + + if(x > 0) { + KERNEL_ELEMENT_C3(5); + KERNEL_ELEMENT_C3(4); + } + + if(x < imgx - 1) { + KERNEL_ELEMENT_C3(7); + KERNEL_ELEMENT_C3(0); + } + + UPDATE_OUTPUT_C3; + } + + dest+= step; + + for(y= 1; y < imgy - 1; y++, dest+= step, src+= pix, ref+= pix) { + x= 0; + + INIT_C3; + + KERNEL_ELEMENT_C3(0); + KERNEL_ELEMENT_C3(1); + KERNEL_ELEMENT_C3(2); + KERNEL_ELEMENT_C3(6); + KERNEL_ELEMENT_C3(7); + + UPDATE_OUTPUT_C3; + + src+= pix; + ref+= pix; + + for(x= 1; x < imgx - 1; x++, src+= pix, ref+= pix) { + INIT_C3; + + KERNEL_ELEMENT_C3(0); + KERNEL_ELEMENT_C3(1); + KERNEL_ELEMENT_C3(2); + KERNEL_ELEMENT_C3(3); + KERNEL_ELEMENT_C3(4); + KERNEL_ELEMENT_C3(5); + KERNEL_ELEMENT_C3(6); + KERNEL_ELEMENT_C3(7); + + UPDATE_OUTPUT_C3; + } + + INIT_C3; + + KERNEL_ELEMENT_C3(2); + KERNEL_ELEMENT_C3(3); + KERNEL_ELEMENT_C3(4); + KERNEL_ELEMENT_C3(5); + KERNEL_ELEMENT_C3(6); + + UPDATE_OUTPUT_C3; + } + + for(x= 0; x < imgx; x++, src+= pix, ref+= pix) { + INIT_C3; + + KERNEL_ELEMENT_C3(2); + + if(x > 0) { + KERNEL_ELEMENT_C3(3); + KERNEL_ELEMENT_C3(4); + } + if(x < imgx - 1) { + KERNEL_ELEMENT_C3(1); + KERNEL_ELEMENT_C3(0); + } + + UPDATE_OUTPUT_C3; + } + + if(node->exec & NODE_BREAK) break; + + SWAP(CompBuf, *source, *new); + } + + if(node->exec & NODE_BREAK) + free_compbuf(source); + + if(img != in[0]->data) + free_compbuf(img); + + if(found_determinator == 1) { + if(refimg != in[1]->data) + free_compbuf(refimg); + } + + out[0]->data= source; + + free_compbuf(new); +} + +static void node_composit_init_bilateralblur(bNode* node) +{ + NodeBilateralBlurData *nbbd= MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data"); + node->storage= nbbd; + nbbd->sigma_color= 0.3; + nbbd->sigma_space= 5.0; +} + +bNodeType cmp_node_bilateralblur= { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_BILATERALBLUR, + /* name */ "Bilateral Blur", + /* width+range */ 150, 120, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_bilateralblur_in, + /* output sock */ cmp_node_bilateralblur_out, + /* storage */ "NodeBilateralBlurData", + /* execfunc */ node_composit_exec_bilateralblur, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_bilateralblur, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL + +}; diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index f641efacdbd..491ecb6e741 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -1142,6 +1142,30 @@ static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *nod return 190; } +static int node_composit_buts_bilateralblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeBilateralBlurData *nbbd= node->storage; + short dy= butr->ymin+38; + short dx= (butr->xmax-butr->xmin); + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Iterations:", + butr->xmin, dy, dx, 19, + &nbbd->iter, 1, 128, 0, 0, "Amount of iterations"); + dy-=19; + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Color Sigma:", + butr->xmin, dy, dx, 19, + &nbbd->sigma_color,0.01, 3, 10, 0, "Sigma value used to modify color"); + dy-=19; + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Space Sigma:", + butr->xmin, dy, dx, 19, + &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space"); + + } + return 57; +} + /* qdn: defocus node */ static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { @@ -1867,6 +1891,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_DBLUR: ntype->butfunc= node_composit_buts_dblur; break; + case CMP_NODE_BILATERALBLUR: + ntype->butfunc= node_composit_buts_bilateralblur; + break; /* qdn: defocus node */ case CMP_NODE_DEFOCUS: ntype->butfunc = node_composit_buts_defocus; From fbc743f3324b63c1b2c6ab0fe2e27fa6b11721dc Mon Sep 17 00:00:00 2001 From: Jens Ole Wund Date: Thu, 27 Dec 2007 22:48:30 +0000 Subject: [PATCH 70/99] fix .. hum not really a bug but waste of CPU remove 6 multiplications and one square root in core spring calculation .. called for every solver step try --- source/blender/blenkernel/intern/softbody.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index bd9d1cb75ca..fdc03a88230 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2307,9 +2307,8 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow) } if (( (sb->totpoint-a) == bs->v1) ){ - actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos); VecSubf(sd,(bproot+bs->v2)->pos, bp->pos); - Normalize(sd); + actspringlen=Normalize(sd); /* friction stuff V1 */ VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec); @@ -2330,9 +2329,8 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow) } if (( (sb->totpoint-a) == bs->v2) ){ - actspringlen= VecLenf( (bproot+bs->v1)->pos, bp->pos); VecSubf(sd,bp->pos,(bproot+bs->v1)->pos); - Normalize(sd); + actspringlen=Normalize(sd); /* friction stuff V2 */ VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec); From 16ea99cbaa95b86fc02d92ad5a5e46558d7f1ae6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Dec 2007 22:58:32 +0000 Subject: [PATCH 71/99] Support for recursive dupli's, now dupliverts and duplifaces can instance empties that intern instance dupligroups. --- source/blender/blenkernel/intern/anim.c | 173 +++++++++++++----------- 1 file changed, 91 insertions(+), 82 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 3a3e55aedeb..76b897f5cb7 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -74,8 +74,9 @@ #include #endif -static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]); -static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]); +#define MAX_DUPLI_RECUR 4 + +static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level); void free_path(Path *path) { @@ -309,7 +310,7 @@ static void group_duplilist(ListBase *lb, Object *ob, int level) group= ob->dup_group; /* simple preventing of too deep nested groups */ - if(level>4) return; + if(level>MAX_DUPLI_RECUR) return; /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ @@ -323,55 +324,24 @@ static void group_duplilist(ListBase *lb, Object *ob, int level) dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0); dob->no_draw= (dob->origlay & group->layer)==0; - /* TODO - This code replicates object_duplilist, should be merged - Campbell */ if(go->ob->transflag & OB_DUPLI) { - if(go->ob->transflag & OB_DUPLIPARTS) { - /* TODO - keep so if's stay the same */ - /* - ParticleSystem *psys = ob->particlesystem.first; - for(; psys; psys=psys->next) - new_particle_duplilist(duplilist, sce, ob, psys); - */ - } - else if(go->ob->transflag & OB_DUPLIVERTS) { - if(go->ob->type==OB_MESH) { - Mat4CpyMat4(dob->ob->obmat, dob->mat); - vertex_duplilist(lb, (ID *)group, go->ob, &ob->obmat); - Mat4CpyMat4(dob->ob->obmat, dob->omat); - } - else if(go->ob->type==OB_FONT) { - /* TODO - does anyone use these ? ;) */ - //font_duplilist(duplilist, ob); - } - } - else if(go->ob->transflag & OB_DUPLIFACES) { - if(go->ob->type==OB_MESH) { - Mat4CpyMat4(dob->ob->obmat, dob->mat); - face_duplilist(lb, (ID *)group, go->ob, &ob->obmat); - Mat4CpyMat4(dob->ob->obmat, dob->omat); - } - } - else if(go->ob->transflag & OB_DUPLIFRAMES) { - /* TODO??? - This one is not easy, maybe we should never support it. - frames_duplilist(duplilist, go->ob);*/ - } else if(ob->transflag & OB_DUPLIGROUP) { - if(go->ob->dup_group) { - Mat4CpyMat4(dob->ob->obmat, dob->mat); - group_duplilist(lb, go->ob, level+1); - Mat4CpyMat4(dob->ob->obmat, dob->omat); - } - } + Mat4CpyMat4(dob->ob->obmat, dob->mat); + object_duplilist_recursive((ID *)group, go->ob, lb, &ob->obmat, level+1); + Mat4CpyMat4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Object *ob) +static void frames_duplilist(ListBase *lb, Object *ob, int level) { extern int enable_cu_speed; /* object.c */ Object copyob; int cfrao, ok; + /* simple preventing of too deep nested groups */ + if(level>MAX_DUPLI_RECUR) return; + cfrao= G.scene->r.cfra; if(ob->parent==NULL && ob->track==NULL && ob->ipo==NULL && ob->constraints.first==NULL) return; @@ -400,6 +370,8 @@ static void frames_duplilist(ListBase *lb, Object *ob) } struct vertexDupliData { + ID *id; /* scene or group, for recursive loops */ + int level; ListBase *lb; float pmat[4][4]; float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ @@ -434,9 +406,17 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n Mat4MulMat43(obmat, tmat, mat); } new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index); + + if(vdd->ob->transflag & OB_DUPLI) { + float tmpmat[4][4]; + Mat4CpyMat4(tmpmat, vdd->ob->obmat); + Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ + object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, &obmat, vdd->level+1); + Mat4CpyMat4(vdd->ob->obmat, tmpmat); + } } -static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]) +static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4], int level) { Object *ob, *ob_iter; Base *base = NULL; @@ -450,6 +430,9 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac Mat4CpyMat4(pmat, par->obmat); + /* simple preventing of too deep nested groups */ + if(level>MAX_DUPLI_RECUR) return; + if(par==G.obedit) dm= editmesh_get_derived_cage(CD_MASK_BAREMESH); else @@ -478,13 +461,14 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac oblay = ob_iter->lay; } - if (ob_iter->type>0 && (lay & oblay) && G.obedit!=ob_iter) { + if (lay & oblay && G.obedit!=ob_iter) { ob=ob_iter->parent; while(ob) { if(ob==par) { ob = ob_iter; /* End Scene/Group object loop, below is generic */ + /* par_space_mat - only used for groups so we can modify the space dupli's are in when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ @@ -493,7 +477,8 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac } else { Mat4CpyMat4(vdd.obmat, ob->obmat); } - + vdd.id= id; + vdd.level= level; vdd.lb= lb; vdd.ob= ob; vdd.par= par; @@ -526,7 +511,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4]) +static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4], int level) { Object *ob, *ob_iter; Base *base = NULL; @@ -541,6 +526,9 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */ + /* simple preventing of too deep nested groups */ + if(level>MAX_DUPLI_RECUR) return; + Mat4CpyMat4(pmat, par->obmat); if(par==G.obedit) { @@ -584,14 +572,13 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ oblay = ob_iter->lay; } - if (ob_iter->type>0 && (lay & oblay) && G.obedit!=ob_iter) { + if (lay & oblay && G.obedit!=ob_iter) { ob=ob_iter->parent; while(ob) { if(ob==par) { ob = ob_iter; /* End Scene/Group object loop, below is generic */ - /* par_space_mat - only used for groups so we can modify the space dupli's are in when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ @@ -645,6 +632,14 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ Mat4MulMat43(obmat, tmat, mat); new_dupli_object(lb, ob, obmat, lay, a); + + if(ob->transflag & OB_DUPLI) { + float tmpmat[4][4]; + Mat4CpyMat4(tmpmat, ob->obmat); + Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */ + object_duplilist_recursive((ID *)id, ob, lb, &ob->obmat, level+1); + Mat4CpyMat4(ob->obmat, tmpmat); + } } break; @@ -664,7 +659,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, Scene *sce, Object *par, ParticleSystem *psys) +static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSystem *psys, int level) { GroupObject *go; Object *ob, **oblist=0; @@ -679,6 +674,11 @@ static void new_particle_duplilist(ListBase *lb, Scene *sce, Object *par, Partic if(psys==0) return; + /* simple preventing of too deep nested groups */ + if(level>MAX_DUPLI_RECUR) return; + + if (GS(id->name)!=ID_SCE) return; /* No support for groups YET! TODO */ + part=psys->part; if(part==0) return; @@ -826,7 +826,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Object *par) +static void font_duplilist(ListBase *lb, Object *par, int level) { Object *ob, *obar[256]; Curve *cu; @@ -834,6 +834,9 @@ static void font_duplilist(ListBase *lb, Object *par) float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; int slen, a; + /* simple preventing of too deep nested groups */ + if(level>MAX_DUPLI_RECUR) return; + Mat4CpyMat4(pmat, par->obmat); /* in par the family name is stored, use this to find the other objects */ @@ -873,45 +876,51 @@ static void font_duplilist(ListBase *lb, Object *par) } /* ***************************** */ +static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level) +{ + if(ob->transflag & OB_DUPLI) { + if(ob->transflag & OB_DUPLIPARTS) { + ParticleSystem *psys = ob->particlesystem.first; + for(; psys; psys=psys->next) + new_particle_duplilist(duplilist, id, ob, psys, level+1); + } + else if(ob->transflag & OB_DUPLIVERTS) { + if(ob->type==OB_MESH) { + vertex_duplilist(duplilist, id, ob, par_space_mat, level+1); + } + else if(ob->type==OB_FONT) { + if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ + font_duplilist(duplilist, ob, level+1); + } + } + } + else if(ob->transflag & OB_DUPLIFACES) { + if(ob->type==OB_MESH) + face_duplilist(duplilist, id, ob, par_space_mat, level+1); + } + else if(ob->transflag & OB_DUPLIFRAMES) { + if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ + frames_duplilist(duplilist, ob, level+1); + } + } else if(ob->transflag & OB_DUPLIGROUP) { + DupliObject *dob; + + group_duplilist(duplilist, ob, level+1); /* now recursive */ + + if (level==0) { + for(dob= duplilist->first; dob; dob= dob->next) + Mat4CpyMat4(dob->ob->obmat, dob->mat); + } + } + } +} /* note; group dupli's already set transform matrix. see note in group_duplilist() */ ListBase *object_duplilist(Scene *sce, Object *ob) { ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist"); duplilist->first= duplilist->last= NULL; - - if(ob->transflag & OB_DUPLI) { - if(ob->transflag & OB_DUPLIPARTS) { - ParticleSystem *psys = ob->particlesystem.first; - for(; psys; psys=psys->next) - new_particle_duplilist(duplilist, sce, ob, psys); - } - else if(ob->transflag & OB_DUPLIVERTS) { - if(ob->type==OB_MESH) { - vertex_duplilist(duplilist, (ID *)sce, ob, NULL); - } - else if(ob->type==OB_FONT) { - font_duplilist(duplilist, ob); - } - } - else if(ob->transflag & OB_DUPLIFACES) { - if(ob->type==OB_MESH) - face_duplilist(duplilist, (ID *)sce, ob, NULL); - } - else if(ob->transflag & OB_DUPLIFRAMES) - frames_duplilist(duplilist, ob); - else if(ob->transflag & OB_DUPLIGROUP) { - DupliObject *dob; - - group_duplilist(duplilist, ob, 0); /* now recursive */ - - /* make copy already, because in group dupli's deform displists can be made, requiring parent matrices */ - for(dob= duplilist->first; dob; dob= dob->next) - Mat4CpyMat4(dob->ob->obmat, dob->mat); - } - - } - + object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0); return duplilist; } From 4a0dc8d4d94f10b93de4a8bf4441e466da70a64b Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Fri, 28 Dec 2007 08:04:37 +0000 Subject: [PATCH 72/99] Bugfix - Socket selection status was not updated properly on file load This commit adds a missing initialization that caused "Toggle Link (f key)" not to work properly in case a file with an existing selection status was opened. --- source/blender/blenloader/intern/readfile.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 043febbbc75..a886c0d195b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1524,6 +1524,22 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link->tosock= newdataadr(fd, link->tosock); } + /* set selin and selout */ + for(node= ntree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ntree->selin= sock; + break; + } + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ntree->selout= sock; + break; + } + } + } + /* type verification is in lib-link */ } From aa9aa530fb7358f4f7b3af90a7e05afed25027ae Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 28 Dec 2007 09:57:06 +0000 Subject: [PATCH 73/99] == Action Editor - Header Buttons Shuffle == * Changed the order of Copy/Paste and AutoSnap buttons * Auto-snap menu now has more descriptive names (off --> No Snap) --- source/blender/src/header_action.c | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index 9e858cb8307..5fa5c6fb97e 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -1241,24 +1241,8 @@ void action_buttons(void) uiClearButLock(); - /* draw AUTOSNAP */ xco += 8; - if (G.saction->flag & SACTION_DRAWTIME) { - uiDefButS(block, MENU, B_REDR, - "Auto-Snap Keyframes %t|Off %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3", - xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, - "Auto-snapping mode for keyframes when transforming"); - } - else { - uiDefButS(block, MENU, B_REDR, - "Auto-Snap Keyframes %t|Off %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3", - xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, - "Auto-snapping mode for keyframes when transforming"); - } - - xco += (70 + 8); - /* COPY PASTE */ uiBlockBeginAlign(block); if (curarea->headertype==HEADERTOP) { @@ -1272,6 +1256,22 @@ void action_buttons(void) uiBlockEndAlign(block); xco += (XIC + 8); + /* draw AUTOSNAP */ + if (G.saction->flag & SACTION_DRAWTIME) { + uiDefButS(block, MENU, B_REDR, + "Auto-Snap Keyframes %t|No Snap %x0|Second Step Snap %x1|Nearest Second Snap %x2|Nearest Marker Snap%x3", + xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, + "Auto-snapping mode for keyframes when transforming"); + } + else { + uiDefButS(block, MENU, B_REDR, + "Auto-Snap Keyframes %t|No Snap %x0|Frame Step Snap %x1|Nearest Frame Snap %x2|Nearest Marker Snap %x3", + xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0, + "Auto-snapping mode for keyframes when transforming"); + } + + xco += (70 + 8); + /* draw LOCK */ uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco, 0, XIC, YIC, &(G.saction->lock), 0, 0, 0, 0, From 1b72bc9792694a1dcd909c183f451afd96872c3f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 28 Dec 2007 12:11:45 +0000 Subject: [PATCH 74/99] small edits noticed when using linked objects, - Make undo string say linked and disallow editing PassIndex and changing the Parent of linked objects. --- source/blender/src/buttons_object.c | 11 +++++++---- source/blender/src/filesel.c | 4 +++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index e5bb4dd8a10..a65323b0606 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2322,23 +2322,26 @@ static void object_panel_object(Object *ob) Group *group; int a, xco, yco=0; short dx= 33, dy= 30; - + int is_libdata = object_is_libdata(ob); block= uiNewBlock(&curarea->uiblocks, "object_panel_object", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Object and Links", "Object", 0, 0, 318, 204)==0) return; - uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + /* object name */ uiBlockSetCol(block, TH_BUT_SETTING2); + uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE); xco= std_libbuttons(block, 10, 180, 0, NULL, 0, ID_OB, 0, &ob->id, NULL, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0, B_KEEPDATA); uiBlockSetCol(block, TH_AUTO); /* parent */ + uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", xco+5, 180, 305-xco, 20, &ob->parent, "Parent Object"); - /* TODO, check for ob->id.lib */ + uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE); but = uiDefButS(block, NUM, B_NOP, "PassIndex:", xco+5, 150, 305-xco, 20, &ob->index, 0.0, 1000.0, 0, 0, "Index # for the IndexOB render pass."); - + + uiSetButLock(1, NULL); uiDefBlockBut(block, add_groupmenu, NULL, "Add to Group", 10,150,150,20, "Add Object to a new Group"); /* all groups */ diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index d4e41e56e75..d6bbedec2b3 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -1421,7 +1421,9 @@ static void filesel_execute(SpaceFile *sfile) } do_library_append(sfile); - BIF_undo_push("Append from file"); + + BIF_undo_push( ((sfile->flag & FILE_LINK)==0) ? "Append from file" : "Link from file"); + allqueue(REDRAWALL, 1); } else if(filesel_has_func(sfile)) { From a85c1c8a65df75a0554aaf08228136033a078dcc Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 28 Dec 2007 13:11:27 +0000 Subject: [PATCH 75/99] Render feature: the END OF DIFFUSE BANDING! http://www.blender.org/development/current-projects/changes-since-244/rendering-features/ Thanks Andy for poking and analysing, and Nathan for feedback! --- source/blender/makesdna/DNA_material_types.h | 5 ++++- source/blender/render/intern/source/shadeoutput.c | 5 ++++- source/blender/src/buttons_shading.c | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index f0b06585f27..dd6b2692de6 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -79,7 +79,7 @@ typedef struct Material { float aniso_gloss_mir; float dist_mir; short fadeto_mir; - short pad1; + short shade_flag; /* like Cubic interpolation */ int mode, mode_l; /* mode_l is the or-ed result of all layer modes */ short flarec, starc, linec, ringc; @@ -201,6 +201,9 @@ typedef struct Material { #define MA_RAYMIR_FADETOSKY 0 #define MA_RAYMIR_FADETOMAT 1 +/* shade_flag */ +#define MA_CUBIC 1 + /* diff_shader */ #define MA_DIFF_LAMBERT 0 #define MA_DIFF_ORENNAYAR 1 diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index a08046da0da..0823ae146f7 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1297,7 +1297,10 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int else is= inp; // Lambert } - /* i is diffuse */ + /* 'is' is diffuse */ + if((ma->shade_flag & MA_CUBIC) && is>0.0f) + is= 3.0*is*is - 2.0*is*is*is; // nicer termination of shades + i= is*phongcorr; if(i>0.0f) { diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index ad1afcc0608..3b597e47fa5 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -3791,7 +3791,8 @@ static void material_panel_shading(Material *ma) uiDefButBitI(block, TOG, MA_SHADOW, B_MATPRV, "Shadow", 245,140,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows"); uiDefButBitI(block, TOG, MA_SHADOW_TRA, B_MATPRV, "TraShadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Receives transparent shadows based at material color and alpha"); uiDefButBitI(block, TOG, MA_ONLYSHADOW, B_MATPRV, "OnlyShad", 245,100,65,20, &(ma->mode), 0, 0, 0, 0, "Renders shadows on material as Alpha value"); - uiDefButBitI(block, TOG, MA_RAYBIAS, B_MATPRV, "Bias", 245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)"); + uiDefButBitS(block, TOG, MA_CUBIC, B_MATPRV, "Cubic", 245,80,65,19, &(ma->shade_flag), 0, 0, 0, 0, "Use Cubic interpolation of diffuse values, for smoother transitions)"); + uiDefButBitI(block, TOG, MA_RAYBIAS, B_MATPRV, "Bias", 245,60,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)"); uiBlockBeginAlign(block); uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_MATPRV, "GR:", 9, 55, 150, 19, &ma->group, "Limit Lighting to Lamps in this Group"); From 64dd90af0b7abb62d3bf786a479061adf54c501b Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Fri, 28 Dec 2007 16:13:52 +0000 Subject: [PATCH 76/99] - particle size changes weren't updated without a cache clear - protecting the particle cache now actually protects the cache a bit better and not just prevent the clear button from working - cache was being used for "none" physics. - a bad tooltip for "reactor initial velocity" --- source/blender/blenkernel/intern/particle_system.c | 6 +++--- source/blender/src/buttons_object.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index db571f01b1e..880fb0c1ef6 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4381,10 +4381,10 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier return; } } - else { - if(psys->recalc) + else if(part->phystype != PART_PHYS_NO) { /* cache shouldn't be used for none physics */ + if(psys->recalc && (psys->flag & PSYS_PROTECT_CACHE) == 0) clear_particles_from_cache(ob,psys,(int)cfra); - else if(get_particles_from_cache(ob, psys, (int)cfra)){ + else if(get_particles_from_cache(ob, psys, (int)cfra)) { cached_step(ob,psmd,psys,cfra,vg_size); psys->cfra=cfra; psys->recalc = 0; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index a65323b0606..d69f5232b37 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3821,9 +3821,9 @@ static void object_panel_particle_extra(Object *ob) uiDefButI(block, NUM, B_PART_DISTR, "Seed:", butx,(buty-=buth),butw,buth, &psys->seed, 0.0, 255.0, 1, 0, "Set an offset in the random table"); - event=(part->flag&PART_SIZEMASS)?B_PART_RECALC:B_PART_REDRAW; - uiDefButF(block, NUM, event, "Size:", butx,(buty-=2*buth),butw,buth, &part->size, 0.01, 100, 10, 1, "The size of the particles"); - uiDefButF(block, NUM, event, "Rand:", butx,(buty-=buth),butw,buth, &part->randsize, 0.0, 2.0, 10, 1, "Give the particle size a random variation"); + /* size changes must create a recalc event always so that sizes are updated properly */ + uiDefButF(block, NUM, B_PART_RECALC, "Size:", butx,(buty-=2*buth),butw,buth, &part->size, 0.01, 100, 10, 1, "The size of the particles"); + uiDefButF(block, NUM, B_PART_RECALC, "Rand:", butx,(buty-=buth),butw,buth, &part->randsize, 0.0, 2.0, 10, 1, "Give the particle size a random variation"); uiDefButBitI(block, TOG, PART_SIZEMASS, B_PART_RECALC, "Mass from size", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Multiply mass with particle size"); uiDefButF(block, NUM, B_PART_RECALC, "Mass:", butx,(buty-=buth),butw,buth, &part->mass, 0.01, 100, 10, 1, "Specify the mass of the particles"); @@ -4122,7 +4122,7 @@ static void object_panel_particle_physics(Object *ob) uiDefButF(block, NUM, B_PART_RECALC, "Random:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->randfac, 0.0, 200.0, 1, 3, "Give the starting speed a random variation"); if(part->type==PART_REACTOR) { uiDefButF(block, NUM, B_PART_RECALC, "Particle:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->partfac, -10.0, 10.0, 1, 3, "Let the target particle give the particle a starting speed"); - uiDefButF(block, NUM, B_PART_RECALC, "Reactor:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->reactfac, -10.0, 10.0, 1, 3, "Let the vector from target particle give the particle a starting speed"); + uiDefButF(block, NUM, B_PART_RECALC, "Reactor:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->reactfac, -10.0, 10.0, 1, 3, "Let the vector away from the target particles location give the particle a starting speed"); } else { uiDefButF(block, NUM, B_PART_RECALC, "Tan:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->tanfac, -200.0, 200.0, 1, 3, "Let the surface tangent give the particle a starting speed"); From 1c02a5f6201ed23545a2fb7157018834502144a0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 28 Dec 2007 17:10:55 +0000 Subject: [PATCH 77/99] Added a new option for 'Apply Object', (Ctrl+A) Called "Apply Visual Transform to Loc/Size/Rot" Since there was no easy way to apply a constraint's transformation back to the original objects transformation. Also adjusted how Apply Scale/Rot works so that it wont change some objects then raise an error and leave others unchanged, better to check first so it changes everything or nothing. --- source/blender/include/BDR_editobject.h | 3 +- source/blender/src/editobject.c | 162 +++++++++++++++++------- source/blender/src/header_view3d.c | 8 +- source/blender/src/toolbox.c | 16 ++- 4 files changed, 131 insertions(+), 58 deletions(-) diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index 51638b258b3..93e7873fe55 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -79,7 +79,8 @@ void link_to_scene(unsigned short nr); void make_links_menu(void); void make_links(short event); void make_duplilist_real(void); -void apply_object(void); +void apply_objects_locrot(void); +void apply_objects_visual_tx(void); /* old transform */ void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert); diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 354d99095f8..5c1742467b7 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -3696,7 +3696,7 @@ void make_links(short event) BIF_undo_push("Create links"); } -void apply_object() +void apply_objects_locrot( void ) { Base *base, *basact; Object *ob; @@ -3707,34 +3707,49 @@ void apply_object() BezTriple *bezt; MVert *mvert; float mat[3][3]; - int a; - - if(G.scene->id.lib) return; - if(G.obedit) return; - basact= BASACT; + int a, change = 0; - if(G.qual & LR_SHIFTKEY) { - ob= OBACT; - if(ob==0) return; - - if(ob->transflag & OB_DUPLI) { - make_duplilist_real(); - } - else { - if(okee("Apply deformation")) { - object_apply_deform(ob); - BIF_undo_push("Apply deformation"); + /* first check if we can execute */ + for (base= FIRSTBASE; base; base= base->next) { + if TESTBASELIB(base) { + ob= base->object; + if(ob->type==OB_MESH) { + if(me->id.us>1) { + error("Can't apply to a multi user mesh, doing nothing."); + return 0; + } + if(me->key) { + error("Can't apply to a mesh with vertex keys, doing nothing."); + return 0; + } + } + else if (ob->type==OB_ARMATURE){ + bArmature *arm; + arm= ob->data; + if(arm->id.us>1) { + error("Can't apply to a multi user armature, doing nothing."); + return 0; + } + } + else if ELEM(ob->type, OB_CURVE, OB_SURF) { + cu= ob->data; + + if(cu->id.us>1) { + error("Can't apply to a multi user curve, doing nothing."); + return 0; + } + if(cu->key) { + error("Can't apply to a curve with vertex keys, doing nothing."); + return 0; + } } } - allqueue(REDRAWVIEW3D, 0); - - return; } - - if(okee("Apply scale and rotation")==0) return; - + + /* now execute */ + basact= BASACT; base= FIRSTBASE; - while(base) { + for (base= FIRSTBASE; base; base= base->next) { if TESTBASELIB(base) { ob= base->object; @@ -3742,14 +3757,7 @@ void apply_object() object_to_mat3(ob, mat); me= ob->data; - if(me->id.us>1) { - error("Can't apply to a multi user mesh"); - return; - } - if(me->key) { - error("Can't apply to a mesh with vertex keys"); - return; - } + /* see checks above */ mvert= me->mvert; for(a=0; atotvert; a++, mvert++) { @@ -3766,19 +3774,18 @@ void apply_object() enter_editmode(EM_WAITCURSOR); BIF_undo_push("Applied object"); /* editmode undo itself */ exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ - BASACT= basact; + BASACT= basact; + change = 1; } else if (ob->type==OB_ARMATURE){ bArmature *arm; object_to_mat3(ob, mat); arm= ob->data; - if(arm->id.us>1) { - error("Can't apply to a multi user armature"); - return; - } - + + /* see checks above */ + apply_rot_armature (ob, mat); /* Reset the object's transforms */ ob->size[0]= ob->size[1]= ob->size[2]= 1.0; @@ -3786,6 +3793,8 @@ void apply_object() QuatOne(ob->quat); where_is_object(ob); + + change = 1; } else if ELEM(ob->type, OB_CURVE, OB_SURF) { float scale; @@ -3793,14 +3802,7 @@ void apply_object() scale = Mat3ToScalef(mat); cu= ob->data; - if(cu->id.us>1) { - error("Can't apply to a multi user curve"); - return; - } - if(cu->key) { - error("Can't apply to a curve with vertex keys"); - return; - } + /* see checks above */ nu= cu->nurb.first; while(nu) { @@ -3838,13 +3840,75 @@ void apply_object() BIF_undo_push("Applied object"); /* editmode undo itself */ exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ BASACT= basact; + + change = 1; } } - base= base->next; } + if (change) { + allqueue(REDRAWVIEW3D, 0); + BIF_undo_push("Apply Objects Scale & Rotation"); + } +} + +void apply_objects_visual_tx( void ) +{ + Base *base; + Object *ob; + int change = 0; - allqueue(REDRAWVIEW3D, 0); - BIF_undo_push("Apply object"); + for (base= FIRSTBASE; base; base= base->next) { + if TESTBASELIB(base) { + ob= base->object; + where_is_object(ob); + VECCOPY(ob->loc, ob->obmat[3]); + Mat4ToSize(ob->obmat, ob->size); + Mat4ToEul(ob->obmat, ob->rot); + + where_is_object(ob); + + change = 1; + } + } + if (change) { + allqueue(REDRAWVIEW3D, 0); + BIF_undo_push("Apply Objects Visual Transform"); + } +} + +void apply_object( void ) +{ + Object *ob; + int evt; + if(G.scene->id.lib) return; + if(G.obedit) return; + + if(G.qual & LR_SHIFTKEY) { + ob= OBACT; + if(ob==0) return; + + if(ob->transflag & OB_DUPLI) { + make_duplilist_real(); + } + else { + if(okee("Apply deformation")) { + object_apply_deform(ob); + BIF_undo_push("Apply deformation"); + } + } + allqueue(REDRAWVIEW3D, 0); + + } else { + + evt = pupmenu("Apply Object%t|Scale and Rotation to ObData|Visual Transform to Objects Loc/Scale/Rot"); + if (evt==-1) return; + + if (evt==1) { + apply_objects_locrot(); + } else if (evt==2) { + apply_objects_visual_tx(); + } + } } diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 4006fd803af..89f21301213 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -1907,7 +1907,10 @@ static void do_view3d_edit_object_transformmenu(void *arg, int event) make_duplilist_real(); break; case 6: /* apply scale/rotation or deformation */ - apply_object(); + apply_objects_locrot(); + break; + case 7: /* apply visual matrix to objects loc/size/rot */ + apply_objects_visual_tx(); break; } allqueue(REDRAWVIEW3D, 0); @@ -1921,7 +1924,8 @@ static uiBlock *view3d_edit_object_transformmenu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "view3d_edit_object_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); uiBlockSetButmFunc(block, do_view3d_edit_object_transformmenu, NULL); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotation|Ctrl A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotationr to ObData|Ctrl A, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Visual Transform|Ctrl A, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Deformation|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Duplicates Real|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 244e1ffd7c3..f9585eff783 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -1272,12 +1272,15 @@ static void tb_do_transform_clearapply(void *arg, int event) clear_object('s'); break; case 3: /* apply scale/rotation */ - apply_object(); + apply_objects_locrot(); break; - case 4: /* apply deformation */ + case 4: /* apply scale/rotation */ + apply_objects_visual_tx(); + break; + case 5: /* apply deformation */ object_apply_deform(ob); break; - case 5: /* make duplicates real */ + case 6: /* make duplicates real */ if (ob->transflag & OB_DUPLI) make_duplilist_real(); else error("The active object does not have dupliverts"); break; @@ -1289,9 +1292,10 @@ static TBitem tb_transform_clearapply[]= { { 0, "Clear Rotation|Alt R", 1, NULL}, { 0, "Clear Scale|Alt S", 2, NULL}, { 0, "SEPR", 0, NULL}, -{ 0, "Apply Scale/Rotation|Ctrl A", 3, NULL}, -{ 0, "Apply Deformation|Shift Ctrl A", 4, NULL}, -{ 0, "Make Duplicates Real|Shift Ctrl A", 5, NULL}, +{ 0, "Apply Scale/Rotation to ObData|Ctrl A, 1", 3, NULL}, +{ 0, "Apply Visual Transform|Ctrl A, 2", 4, NULL}, +{ 0, "Apply Deformation|Shift Ctrl A", 5, NULL}, +{ 0, "Make Duplicates Real|Shift Ctrl A", 6, NULL}, { -1, "", 0, tb_do_transform_clearapply}}; static TBitem tb_transform_snap[]= { From c3ecba1d65c7e644c713646683c2be778aba93bf Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 28 Dec 2007 18:58:40 +0000 Subject: [PATCH 78/99] And there's another annoyance I got poked for: Image texture "Filter size" was not well usable for making the appearance soft filtered, this because it multiplied the sample values, and such values could be extreme small. Added next to "Filter" buton a new "Min" option, which enforces a filter size to be a minimum of 'filter' pixels in size. --- source/blender/makesdna/DNA_texture_types.h | 1 + source/blender/render/intern/source/imagetexture.c | 9 +++++++++ source/blender/src/buttons_shading.c | 5 +++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 14ece2b31b2..182ac6025fd 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -248,6 +248,7 @@ typedef struct TexMapping { #define TEX_CALCALPHA 32 #define TEX_NORMALMAP 2048 #define TEX_GAUSS_MIP 4096 +#define TEX_FILTER_MIN 8192 /* imaflag unused, only for version check */ #define TEX_FIELDS_ 8 diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 23b5e597070..cc0ce57bb99 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -702,6 +702,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, f minx= tex->filtersize*(maxx-minx)/2.0f; miny= tex->filtersize*(maxy-miny)/2.0f; + if(tex->imaflag & TEX_FILTER_MIN) { + /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */ + float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y); + + if(addval > minx) + minx= addval; + if(addval > miny) + miny= addval; + } if(tex->filtersize!=1.0f) { dxt[0]*= tex->filtersize; dxt[1]*= tex->filtersize; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 3b597e47fa5..c82aee0155a 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -1244,9 +1244,10 @@ static void texture_panel_image_map(Tex *tex, MTex *mtex) uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha", 10, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel"); uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha", 110, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values"); uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha", 210, 160, 100, 20, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values"); - uiBlockEndAlign(block); - uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,120,150,20, &tex->filtersize, 0.1, 25.0, 10, 3, "Sets the filter size used by mipmap and interpol"); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, TEX_FILTER_MIN, B_TEXPRV, "Min", 10, 120, 30, 20, &tex->imaflag, 0, 0, 0, 0, "Use Filtersize as a minimal filter value in pixels"); + uiDefButF(block, NUM, B_TEXPRV, "Filter: ", 40,120,120,20, &tex->filtersize, 0.1, 25.0, 10, 3, "Multiplies the filter size used by mipmap and interpol"); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,120,(mtex)? 75: 150,20, &tex->imaflag, From 6a5ce69a162f3b48f0c4a94e820360fa524e8639 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 28 Dec 2007 19:38:47 +0000 Subject: [PATCH 79/99] Error in previous commit: the texture filter size should not be scaled at all if you use new 'minimal' option. The new option works much nicer if it only sets the minimum. (use texture with 'refl' map) Added option to env map too! --- source/blender/render/intern/source/imagetexture.c | 9 ++++++--- source/blender/render/intern/source/texture.c | 2 +- source/blender/src/buttons_shading.c | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index cc0ce57bb99..b950f54417e 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -699,8 +699,8 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, f maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] ); /* tex_sharper has been removed */ - minx= tex->filtersize*(maxx-minx)/2.0f; - miny= tex->filtersize*(maxy-miny)/2.0f; + minx= (maxx-minx)/2.0f; + miny= (maxy-miny)/2.0f; if(tex->imaflag & TEX_FILTER_MIN) { /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */ @@ -711,7 +711,10 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, f if(addval > miny) miny= addval; } - if(tex->filtersize!=1.0f) { + else if(tex->filtersize!=1.0f) { + minx*= tex->filtersize; + miny*= tex->filtersize; + dxt[0]*= tex->filtersize; dxt[1]*= tex->filtersize; dyt[0]*= tex->filtersize; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index b502fb2b421..0c0fd6edbd2 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -98,7 +98,7 @@ void init_render_texture(Render *re, Tex *tex) } else if(tex->type==TEX_ENVMAP) { /* just in case */ - tex->imaflag= TEX_INTERPOL | TEX_MIPMAP; + tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP; tex->extend= TEX_CLIP; if(tex->env) { diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index c82aee0155a..6d846e69308 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -1247,7 +1247,7 @@ static void texture_panel_image_map(Tex *tex, MTex *mtex) uiBlockBeginAlign(block); uiDefButBitS(block, TOG, TEX_FILTER_MIN, B_TEXPRV, "Min", 10, 120, 30, 20, &tex->imaflag, 0, 0, 0, 0, "Use Filtersize as a minimal filter value in pixels"); - uiDefButF(block, NUM, B_TEXPRV, "Filter: ", 40,120,120,20, &tex->filtersize, 0.1, 25.0, 10, 3, "Multiplies the filter size used by mipmap and interpol"); + uiDefButF(block, NUM, B_TEXPRV, "Filter: ", 40,120,120,20, &tex->filtersize, 0.1, 50.0, 10, 3, "Multiplies the filter size used by mipmap and interpol"); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,120,(mtex)? 75: 150,20, &tex->imaflag, @@ -1369,7 +1369,8 @@ static void texture_panel_envmap(Tex *tex) uiDefButS(block, NUM, B_ENV_FREE, "CubeRes", 160,90,150,20, &env->cuberes, 50, 4096.0, 0, 0, "Sets the pixel resolution of the rendered environment map"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,65,150,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Adjusts sharpness or blurriness of the reflection"), + uiDefButBitS(block, TOG, TEX_FILTER_MIN, B_TEXPRV, "Min", 10, 65, 30, 20, &tex->imaflag, 0, 0, 0, 0, "Use Filtersize as a minimal filter value in pixels"); + uiDefButF(block, NUM, B_TEXPRV, "Filter :", 40,65,120,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Adjusts sharpness or blurriness of the reflection"), uiDefButS(block, NUM, B_ENV_FREE, "Depth:", 160,65,150,20, &env->depth, 0, 5.0, 0, 0, "Sets the number of times a map will be rendered recursively mirror effects"), uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 10,40,150,20, &env->clipsta, 0.01, 50.0, 100, 0, "Sets start value for clipping: objects nearer than this are not visible to map"); uiDefButF(block, NUM, B_NOP, "ClipEnd", 160,40,150,20, &env->clipend, 0.1, 20000.0, 1000, 0, "Sets end value for clipping beyond which objects are not visible to map"); From 81cdf2428405f7390c4f3e0973ab4ea567e3cf7a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 28 Dec 2007 21:16:00 +0000 Subject: [PATCH 80/99] Fix for [#7866] Relative Path to library from command line http://projects.blender.org/tracker/index.php?func=detail&aid=7866&group_id=9&atid=125 where linked relative blend files would not load when the absolute path was not given. Solved by constructing the absolute path from the command line argument given. --- source/creator/creator.c | 49 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 6a780553607..e5abe425468 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -687,9 +687,50 @@ int main(int argc, char **argv) break; } } - else { + else { + + /* Make the path absolute because its needed for relative linked blends to be found */ + int abs = 0; + int filelen; + char cwd[FILE_MAXDIR + FILE_MAXFILE]; + char filename[FILE_MAXDIR + FILE_MAXFILE]; + cwd[0] = filename[0] = '\0'; + + BLI_strncpy(filename, argv[a], sizeof(filename)); + filelen = strlen(filename); + + /* relative path checks, could do more tests here... */ +#ifdef WIN32 + /* Account for X:/ and X:\ - should be enough */ + if (filelen >= 3 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/')) + abs = 1; +#else + if (filelen >= 2 && filename[0] == '/') + abs = 1 ; +#endif + if (!abs) { + BLI_getwdN(cwd); /* incase the full path to the blend isnt used */ + + if (cwd[0] == '\0') { + printf( + "Could not get the current working directory - $PWD for an unknown reason.\n\t" + "Relative linked files will not load if the entire blend path is not used.\n\t" + "The 'Play' button may also fail.\n" + ); + } else { + /* uses the blend path relative to cwd important for loading relative linked files. + * + * cwd should contain c:\ etc on win32 so the relbase can be NULL + * relbase being NULL also prevents // being misunderstood as relative to the current + * blend file which isnt a feature we want to use in this case since were dealing + * with a path from the command line, rather then from inside Blender */ + + BLI_make_file_string(NULL, filename, cwd, argv[a]); + } + } + if (G.background) { - BKE_read_file(argv[a], NULL); + BKE_read_file(filename, NULL); sound_initialize_sounds(); /* happens for the UI on file reading too */ @@ -698,8 +739,8 @@ int main(int argc, char **argv) } else { /* we are not running in background mode here, but start blender in UI mode with a file - this should do everything a 'load file' does */ - BIF_read_file(argv[a]); - } + BIF_read_file(filename); + } } } From 02b00e2fd742401aa1232e5b0e4dc618f268e9f3 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 29 Dec 2007 05:16:00 +0000 Subject: [PATCH 81/99] * Displacement map baking This is an extension on the work Brecht already did to implement normal map baking. I've updated the release notes page here with info and pics: http://www.blender.org/development/current-projects/changes-since-244/render-baking/ --- CMakeLists.txt | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0227c51f39d..78418d18888 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,16 +57,16 @@ SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) #----------------------------------------------------------------------------- # Set default config options OPTION(WITH_PLAYER "Build Player" OFF) -OPTION(WITH_GAMEENGINE "Enable Game Engine" ON) -OPTION(WITH_BULLET "Enable Bullet (Physics Engine)" ON) +OPTION(WITH_GAMEENGINE "Enable Game Engine" OFF) +OPTION(WITH_BULLET "Enable Bullet (Physics Engine)" OFF) OPTION(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON) OPTION(WITH_VERSE "Enable Verse (http://verse.blender.org)" OFF) OPTION(WITH_ELBEEM "Enable Elbeem (Fluid Simulation)" ON) -OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF) -OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" OFF) +OPTION(WITH_QUICKTIME "Enable Quicktime Support" ON) +OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON) OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF) -OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) -OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF) +OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) +OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" ON) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE") @@ -299,22 +299,28 @@ IF(APPLE) SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) - INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) - IF(OPENAL_FOUND) - SET(WITH_OPENAL ON) - SET(OPENAL_LIB ${OPENAL_LIBRARY}) - SET(OPENAL_INC ${OPENAL_INCLUDE_DIR}) - ELSE(OPENAL_FOUND) - SET(WITH_OPENAL OFF) - ENDIF(OPENAL_FOUND) + #INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + #IF(OPENAL_FOUND) + # SET(WITH_OPENAL ON) + # SET(OPENAL_LIB ${OPENAL_LIBRARY}) + # SET(OPENAL_INC ${OPENAL_INCLUDE_DIR}) + #ELSE(OPENAL_FOUND) + # SET(WITH_OPENAL OFF) + #ENDIF(OPENAL_FOUND) + + SET(WITH_OPENAL ON) + SET(OPENAL ${LIBDIR}/openal) + SET(OPENAL_INC ${OPENAL}/include) + SET(OPENAL_LIBPATH ${OPENAL}/lib) + SET(OPENAL_LIB openal) SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/) - SET(PYTHON_VERSION 2.3) + SET(PYTHON_VERSION 2.5) SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "") SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "") SET(PYTHON_LIB "") SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "") - SET(PYTHON_LINKFLAGS "-u __dummy -u _PyMac_Error -framework System -framework Python") + SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python") SET(GETTEXT ${LIBDIR}/gettext) SET(GETTEXT_INC "${GETTEXT}/include") From 3c1ad6a295af33ee97847d80ff1e007369bdf96f Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 29 Dec 2007 05:17:19 +0000 Subject: [PATCH 82/99] * Displacement map baking This is an extension on the work Brecht already did to implement normal map baking. I've updated the release notes page here with info and pics: http://www.blender.org/development/current-projects/changes-since-244/render-baking/ --- source/blender/blenkernel/BKE_image.h | 2 +- source/blender/blenkernel/intern/image.c | 92 ++++++++++++++----- source/blender/imbuf/intern/filter.c | 54 ++++++++++- source/blender/python/api2_2x/Image.c | 4 +- source/blender/python/api2_2x/bpy_data.c | 4 +- .../render/extern/include/RE_pipeline.h | 11 ++- .../render/intern/source/convertblender.c | 5 +- .../blender/render/intern/source/rendercore.c | 34 ++++++- source/blender/src/buttons_scene.c | 5 +- source/blender/src/editsima.c | 6 +- source/blender/src/header_info.c | 28 ++++-- source/blender/src/meshtools.c | 5 +- source/blender/src/verse_object.c | 1 + 13 files changed, 197 insertions(+), 54 deletions(-) diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index b308342ac1e..47716e66077 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -114,7 +114,7 @@ struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser); struct Image *BKE_add_image_file(const char *name); /* adds image, adds ibuf, generates color or pattern */ -struct Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, float color[4]); +struct Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]); /* for reload, refresh, pack */ void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index dc8a020a189..d61829891d6 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -378,20 +378,27 @@ Image *BKE_add_image_file(const char *name) return ima; } -static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, float color[4]) +static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]) { ImBuf *ibuf; float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b; unsigned char *rect; + float *rect_float; int x, y; int checkerwidth=21, dark=1; - ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0); + if (floatbuf) { + ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0); + rect_float= (float*)ibuf->rect_float; + } + else { + ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0); + rect= (unsigned char*)ibuf->rect; + } + strcpy(ibuf->name, "Untitled"); ibuf->userflags |= IB_BITMAPDIRTY; - rect= (unsigned char*)ibuf->rect; - if (uvtestgrid) { /* these two passes could be combined into one, but it's more readable and * easy to tweak like this, speed isn't really that much of an issue in this situation... */ @@ -400,26 +407,40 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, for(y=0; yy; y++) { dark = pow(-1, floor(y / checkerwidth)); - for(x=0; xx; x++, rect+=4) { + for(x=0; xx; x++) { if (x % checkerwidth == 0) dark *= -1; - if (dark > 0) { - rect[0] = rect[1] = rect[2] = 64; - rect[3] = 255; - } else { - rect[0] = rect[1] = rect[2] = 150; - rect[3] = 255; + if (floatbuf) { + if (dark > 0) { + rect_float[0] = rect_float[1] = rect_float[2] = 0.25; + rect_float[3] = 1.0; + } else { + rect_float[0] = rect_float[1] = rect_float[2] = 0.58; + rect_float[3] = 1.0; + } + rect_float+=4; + } + else { + if (dark > 0) { + rect[0] = rect[1] = rect[2] = 64; + rect[3] = 255; + } else { + rect[0] = rect[1] = rect[2] = 150; + rect[3] = 255; + } + rect += 4; } } } /* 2nd pass, colored + */ - rect= (unsigned char*)ibuf->rect; + if (floatbuf) rect_float= (float*)ibuf->rect_float; + else rect= (unsigned char*)ibuf->rect; for(y=0; yy; y++) { hoffs = 0.125 * floor(y / checkerwidth); - for(x=0; xx; x++, rect+=4) { + for(x=0; xx; x++) { h = 0.125 * floor(x / checkerwidth); if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) && @@ -431,10 +452,20 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, hue = fmod(fabs(h-hoffs), 1.0); hsv_to_rgb(hue, s, v, &r, &g, &b); - rect[0]= (char)(r * 255.0); - rect[1]= (char)(g * 255.0); - rect[2]= (char)(b * 255.0); - rect[3]= 255; + if (floatbuf) { + rect_float[0]= r; + rect_float[1]= g; + rect_float[2]= b; + rect_float[3]= 1.0; + rect_float+=4; + } + else { + rect[0]= (char)(r * 255.0); + rect[1]= (char)(g * 255.0); + rect[2]= (char)(b * 255.0); + rect[3]= 255; + rect+=4; + } } } @@ -442,11 +473,21 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, } } else { /* blank image */ for(y=0; yy; y++) { - for(x=0; xx; x++, rect+=4) { - rect[0]= (char)(color[0] * 255.0); - rect[1]= (char)(color[1] * 255.0); - rect[2]= (char)(color[2] * 255.0); - rect[3]= (char)(color[3] * 255.0); + for(x=0; xx; x++) { + if (floatbuf) { + rect_float[0]= color[0]; + rect_float[1]= color[1]; + rect_float[2]= color[2]; + rect_float[3]= color[3]; + rect_float+=4; + } + else { + rect[0]= (char)(color[0] * 255.0); + rect[1]= (char)(color[1] * 255.0); + rect[2]= (char)(color[2] * 255.0); + rect[3]= (char)(color[3] * 255.0); + rect+=4; + } } } } @@ -454,7 +495,7 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, } /* adds new image block, creates ImBuf and initializes color */ -Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, float color[4]) +Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]) { Image *ima; @@ -469,7 +510,7 @@ Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, f ima->gen_y= height; ima->gen_type= uvtestgrid; - ibuf= add_ibuf_size(width, height, name, uvtestgrid, color); + ibuf= add_ibuf_size(width, height, name, floatbuf, uvtestgrid, color); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); ima->ok= IMA_OK_LOADED; @@ -1678,6 +1719,7 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) { ImBuf *ibuf= NULL; float color[] = {0, 0, 0, 1}; + int floatbuf; /* quick reject tests */ if(ima==NULL) @@ -1755,7 +1797,7 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) /* UV testgrid or black or solid etc */ if(ima->gen_x==0) ima->gen_x= 256; if(ima->gen_y==0) ima->gen_y= 256; - ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_type, color); + ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, floatbuf, ima->gen_type, color); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); ima->ok= IMA_OK_LOADED; } diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c index fd9dac1af2b..172342c913c 100644 --- a/source/blender/imbuf/intern/filter.c +++ b/source/blender/imbuf/intern/filter.c @@ -242,7 +242,7 @@ void IMB_filter(struct ImBuf *ibuf) #define EXTEND_PIXEL(a, w) if((a)[3]) {r+= w*(a)[0]; g+= w*(a)[1]; b+= w*(a)[2]; tot+=w;} -/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 255 */ +/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0 */ void IMB_filter_extend(struct ImBuf *ibuf) { register char *row1, *row2, *row3; @@ -251,7 +251,57 @@ void IMB_filter_extend(struct ImBuf *ibuf) rowlen= ibuf->x; - if(ibuf->rect) { + + if (ibuf->rect_float) { + float *temprect; + float *row1f, *row2f, *row3f; + float *fp; + int pixlen = 4; + temprect= MEM_dupallocN(ibuf->rect_float); + + for(y=1; y<=ibuf->y; y++) { + /* setup rows */ + row1f= (float *)(temprect + (y-2)*rowlen*4); + row2f= row1f + 4*rowlen; + row3f= row2f + 4*rowlen; + if(y==1) + row1f= row2f; + else if(y==ibuf->y) + row3f= row2f; + + fp= (float *)(ibuf->rect_float + (y-1)*rowlen*4); + + for(x=0; xrect) { int *temprect; /* make a copy, to prevent flooding */ diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c index f68cb2d8eeb..ec822004596 100644 --- a/source/blender/python/api2_2x/Image.c +++ b/source/blender/python/api2_2x/Image.c @@ -1,5 +1,5 @@ /* - * $Id: Image.c 11241 2007-07-12 11:51:21Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -243,7 +243,7 @@ static PyObject *M_Image_New( PyObject * self, PyObject * args) if (width > 5000 || height > 5000 || width < 1 || height < 1) return ( EXPP_ReturnPyObjError( PyExc_TypeError, "Image width and height must be between 1 and 5000" ) ); - image = BKE_add_image_size(width, height, name, 0, color); + image = BKE_add_image_size(width, height, name, 0, 0, color); if( !image ) return ( EXPP_ReturnPyObjError( PyExc_MemoryError, "couldn't create PyObject Image_Type" ) ); diff --git a/source/blender/python/api2_2x/bpy_data.c b/source/blender/python/api2_2x/bpy_data.c index fd5fe27fbaf..8ad577bd175 100644 --- a/source/blender/python/api2_2x/bpy_data.c +++ b/source/blender/python/api2_2x/bpy_data.c @@ -1,5 +1,5 @@ /* - * $Id: bpy_data.c 12056 2007-09-17 06:11:06Z aligorith $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -538,7 +538,7 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd) break; case ID_IM: { - id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", 0, color); + id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", 0, 0, color); if( !id ) return ( EXPP_ReturnPyObjError( PyExc_MemoryError, "couldn't create PyObject Image_Type" ) ); diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index d202ea1eed5..846b0867a76 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -206,11 +206,12 @@ float RE_filter_value(int type, float x); void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect); /* shaded view or baking options */ -#define RE_BAKE_LIGHT 0 -#define RE_BAKE_ALL 1 -#define RE_BAKE_AO 2 -#define RE_BAKE_NORMALS 3 -#define RE_BAKE_TEXTURE 4 +#define RE_BAKE_LIGHT 0 +#define RE_BAKE_ALL 1 +#define RE_BAKE_AO 2 +#define RE_BAKE_NORMALS 3 +#define RE_BAKE_TEXTURE 4 +#define RE_BAKE_DISPLACEMENT 5 void RE_Database_Baking(struct Render *re, struct Scene *scene, int type, struct Object *actob); void RE_DataBase_GetView(struct Render *re, float mat[][4]); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index eb5bb3f2f71..68c32ee2d8b 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4706,6 +4706,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce) RE_BAKE_NORMALS:for baking, no lamps and only selected objects RE_BAKE_AO: for baking, no lamps, but all objects RE_BAKE_TEXTURE:for baking, no lamps, only selected objects + RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects */ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) { @@ -4724,7 +4725,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) if(type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT) re->flag |= R_NEED_TANGENT; - if(!actob && ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE)) { + if(!actob && ELEM4(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT)) { re->r.mode &= ~R_SHADOW; re->r.mode &= ~R_RAYTRACE; } @@ -4767,7 +4768,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) /* MAKE RENDER DATA */ nolamps= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL); - onlyselected= ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE); + onlyselected= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT); database_init_objects(re, lay, nolamps, onlyselected, actob, 0); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 0a9078b32f0..5b9a275ad32 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1870,6 +1870,26 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int } } +static void bake_displacement(void *handle, ShadeInput *shi, Isect *isec, int dir, int x, int y) +{ + BakeShade *bs= handle; + float disp; + + disp = 0.5 + (isec->labda*VecLength(isec->vec) * -dir); + + if(bs->rect_float) { + float *col= bs->rect_float + 4*(bs->rectx*y + x); + col[0] = col[1] = col[2] = disp; + col[3]= 1.0f; + } else { + char *col= (char *)(bs->rect + bs->rectx*y + x); + col[0]= FTOCHAR(disp); + col[1]= FTOCHAR(disp); + col[2]= FTOCHAR(disp); + col[3]= 255; + } +} + static int bake_check_intersect(Isect *is, RayFace *face) { VlakRen *vlr = (VlakRen*)face; @@ -1956,7 +1976,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if(bs->actob) { Isect isec, minisec; float co[3], minco[3]; - int hit, sign; + int hit, sign, dir; /* intersect with ray going forward and backward*/ hit= 0; @@ -1978,10 +1998,16 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) minisec= isec; VECCOPY(minco, co); hit= 1; + dir = sign; } } } + if (hit && bs->type==RE_BAKE_DISPLACEMENT) {; + bake_displacement(handle, shi, &minisec, dir, x, y); + return; + } + /* if hit, we shade from the new point, otherwise from point one starting face */ if(hit) { vlr= (VlakRen*)minisec.face; @@ -1993,6 +2019,8 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) v= -minisec.v; bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v); } + + } if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) @@ -2184,13 +2212,15 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob) break; } - /* filter images */ + /* filter and refresh images */ for(ima= G.main->image.first; ima; ima= ima->id.next) { if((ima->id.flag & LIB_DOIT)==0) { ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); for(a=0; ar.bake_filter; a++) IMB_filter_extend(ibuf); ibuf->userflags |= IB_BITMAPDIRTY; + + if (ibuf->rect_float) IMB_rect_from_float(ibuf); } } diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 5c9cacdb2fc..820daeef6db 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1895,11 +1895,12 @@ static void render_panel_bake(void) uiDefButS(block, ROW,B_REDR,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, ""); uiDefButS(block, ROW,B_REDR,"Normals", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, ""); uiDefButS(block, ROW,B_REDR,"Textures", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, ""); + uiDefButS(block, ROW,B_REDR,"Displacement", 210,90,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_DISPLACEMENT, 0, 0, ""); uiBlockEndAlign(block); - uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,80,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking"); + uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,60,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking"); - uiDefButS(block, NUM, B_DIFF,"Margin:", 210,50,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter"); + uiDefButS(block, NUM, B_DIFF,"Margin:", 210,30,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter"); } static void render_panel_render(void) diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index eb70a32b5a9..c5215615618 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -2218,6 +2218,7 @@ void new_image_sima(void) { static int width= 1024, height= 1024; static short uvtestgrid= 0; + static int floatbuf=0; static float color[] = {0, 0, 0, 1}; char name[22]; Image *ima; @@ -2230,10 +2231,11 @@ void new_image_sima(void) add_numbut(3, COL, "", 0, 0, &color, NULL); add_numbut(4, NUM|FLO, "Alpha:", 0.0, 1.0, &color[3], NULL); add_numbut(5, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL); - if (!do_clever_numbuts("New Image", 6, REDRAW)) + add_numbut(6, TOG|INT, "32 bit Float", 0, 0, &floatbuf, NULL); + if (!do_clever_numbuts("New Image", 7, REDRAW)) return; - ima = BKE_add_image_size(width, height, name, uvtestgrid, color); + ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color); image_changed(G.sima, ima); BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); BIF_undo_push("Add image"); diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index beb3eb52820..552201445d1 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -1724,8 +1724,13 @@ static uiBlock *info_timelinemenu(void *arg_unused) void do_info_render_bakemenu(void *arg, int event) { - - objects_bake_render(event); + switch (event) { + case R_BAKE_TO_ACTIVE: + G.scene->r.bake_flag ^= event; + break; + default: + objects_bake_render(event); + } allqueue(REDRAWINFO, 0); } @@ -1733,15 +1738,24 @@ void do_info_render_bakemenu(void *arg, int event) static uiBlock *info_render_bakemenu(void *arg_unused) { uiBlock *block; - short yco= 0; + short yco= 0, menuwidth=160; block= uiNewBlock(&curarea->uiblocks, "render_bakemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); uiBlockSetButmFunc(block, do_info_render_bakemenu, NULL); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Full Render|Ctrl Alt B, 1", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ambient Occlusion|Ctrl Alt B, 2", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Normals|Ctrl Alt B, 3", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Texture Only|Ctrl Alt B, 4", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, ""); + if(G.scene->r.bake_flag & R_BAKE_TO_ACTIVE) { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, R_BAKE_TO_ACTIVE, ""); + } else { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, R_BAKE_TO_ACTIVE, ""); + } + + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Full Render|Ctrl Alt B, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ambient Occlusion|Ctrl Alt B, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Normals|Ctrl Alt B, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Texture Only|Ctrl Alt B, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Displacement|Ctrl Alt B, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); uiBlockSetDirection(block, UI_RIGHT); uiTextBoundsBlock(block, 50); diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index bcf07c9b594..d75493def9d 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -1009,7 +1009,7 @@ void objects_bake_render_menu(void) { short event; - event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4"); + event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5"); objects_bake_render(event); } @@ -1043,7 +1043,8 @@ void objects_bake_render(short event) if(event==1) event= RE_BAKE_ALL; else if(event==2) event= RE_BAKE_AO; else if(event==3) event= RE_BAKE_NORMALS; - else event= RE_BAKE_TEXTURE; + else if(event==4) event= RE_BAKE_TEXTURE; + else event= RE_BAKE_DISPLACEMENT; if(event==RE_BAKE_AO) { if(G.scene->world==NULL) { diff --git a/source/blender/src/verse_object.c b/source/blender/src/verse_object.c index fc937469d42..107aae59845 100644 --- a/source/blender/src/verse_object.c +++ b/source/blender/src/verse_object.c @@ -295,6 +295,7 @@ void b_verse_pop_node(VNode *vnode) vbitmap->height, vnode->name, 0, + 0, color); ((Image*)vbitmap->image)->vnode = (void*)vnode; sync_blender_image_with_verse_bitmap_node(vnode); From 96935a6c5d35974e08604a9c338b8dcd06a7b9f8 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 29 Dec 2007 05:29:08 +0000 Subject: [PATCH 83/99] Reverting mistaken CMakeLists.txt commit, woops! --- CMakeLists.txt | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78418d18888..0227c51f39d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,16 +57,16 @@ SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) #----------------------------------------------------------------------------- # Set default config options OPTION(WITH_PLAYER "Build Player" OFF) -OPTION(WITH_GAMEENGINE "Enable Game Engine" OFF) -OPTION(WITH_BULLET "Enable Bullet (Physics Engine)" OFF) +OPTION(WITH_GAMEENGINE "Enable Game Engine" ON) +OPTION(WITH_BULLET "Enable Bullet (Physics Engine)" ON) OPTION(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON) OPTION(WITH_VERSE "Enable Verse (http://verse.blender.org)" OFF) OPTION(WITH_ELBEEM "Enable Elbeem (Fluid Simulation)" ON) -OPTION(WITH_QUICKTIME "Enable Quicktime Support" ON) -OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON) +OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF) +OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" OFF) OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF) -OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) -OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" ON) +OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) +OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE") @@ -299,28 +299,22 @@ IF(APPLE) SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) - #INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) - #IF(OPENAL_FOUND) - # SET(WITH_OPENAL ON) - # SET(OPENAL_LIB ${OPENAL_LIBRARY}) - # SET(OPENAL_INC ${OPENAL_INCLUDE_DIR}) - #ELSE(OPENAL_FOUND) - # SET(WITH_OPENAL OFF) - #ENDIF(OPENAL_FOUND) - - SET(WITH_OPENAL ON) - SET(OPENAL ${LIBDIR}/openal) - SET(OPENAL_INC ${OPENAL}/include) - SET(OPENAL_LIBPATH ${OPENAL}/lib) - SET(OPENAL_LIB openal) + INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + IF(OPENAL_FOUND) + SET(WITH_OPENAL ON) + SET(OPENAL_LIB ${OPENAL_LIBRARY}) + SET(OPENAL_INC ${OPENAL_INCLUDE_DIR}) + ELSE(OPENAL_FOUND) + SET(WITH_OPENAL OFF) + ENDIF(OPENAL_FOUND) SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/) - SET(PYTHON_VERSION 2.5) + SET(PYTHON_VERSION 2.3) SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "") SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "") SET(PYTHON_LIB "") SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "") - SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python") + SET(PYTHON_LINKFLAGS "-u __dummy -u _PyMac_Error -framework System -framework Python") SET(GETTEXT ${LIBDIR}/gettext) SET(GETTEXT_INC "${GETTEXT}/include") From 5be2e5aa9821a1da9cf16d7dd848a17487f68685 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Dec 2007 12:08:28 +0000 Subject: [PATCH 84/99] == PoseLib - Overhauled Implementation == Based on feedback from Ton, I've recoded the way "PoseLibs" are implemented/exposed. Therefore, quite a bit of code has been changed to fit this in better. Now, ANY ACTION can be a "PoseLib". A set of Markers which belong to the Action (it's taken a year, but they're finally back), are used to tag "poses" in the Action. These markers are shown using diamond-shaped blue icons (designed by Matt Ebb) in three shades - unselected/normal, selected, active. Notes: * Each Armature Object has an Action which acts as a PoseLib. * Improved UI presented in buttons panel for this -- added proper buttons for action assigning -- renamed "Validate PoseLib" to "Auto-Sync PoseLib" (this option auto-tags poses based on keyframes found) Like in the 3d-view, use the hotkeys: * Shift-L to add a local marker * Ctrl-Shift-L to rename a local marker * Alt-L to delete selected local markers Note: transforms, etc. are not currently available with these markers == PoseLib Preview == Added a few features here: * Left/Right-Arrow keys now change the poses too (previous and next respectively) * Up/Down-Arrow keys also change the poses, but "jump" to a pose 5 steps away in their respective directions --- release/datafiles/blenderbuttons | Bin 64418 -> 65462 bytes source/blender/blenkernel/intern/action.c | 15 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenloader/intern/readfile.c | 12 +- source/blender/blenloader/intern/writefile.c | 11 +- source/blender/include/BIF_editaction.h | 9 +- source/blender/include/BIF_poselib.h | 15 +- source/blender/include/BIF_resources.h | 6 +- source/blender/include/BSE_time.h | 22 +- source/blender/include/butspace.h | 15 +- source/blender/makesdna/DNA_action_types.h | 26 +- source/blender/makesdna/DNA_object_types.h | 1 + source/blender/src/blenderbuttons.c | 4062 +++++++++--------- source/blender/src/buttons_editing.c | 158 +- source/blender/src/drawaction.c | 8 +- source/blender/src/drawipo.c | 2 +- source/blender/src/drawnla.c | 2 +- source/blender/src/drawseq.c | 2 +- source/blender/src/drawsound.c | 2 +- source/blender/src/drawtime.c | 54 +- source/blender/src/editaction.c | 238 +- source/blender/src/editipo.c | 2 +- source/blender/src/editnla.c | 2 +- source/blender/src/editseq.c | 2 +- source/blender/src/editsound.c | 2 +- source/blender/src/edittime.c | 10 +- source/blender/src/header_action.c | 23 +- source/blender/src/headerbuttons.c | 9 +- source/blender/src/poselib.c | 381 +- 29 files changed, 2693 insertions(+), 2400 deletions(-) diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons index d447b3b4f2c61f712cee19c4447627b8f29c1054..3f897f7d1c46a3b8c880188f87fa5e01967d9a23 100644 GIT binary patch delta 9900 zcmXw~zPOh0U1hl*|)SjDo=Zv%FKDB?HGd7a( zZ2Y=?TWZ^^{0Ab6j(6=e!-);#m1zUJ3k4e>V%u?ot_bE?(IN?gYmMFaH++YarimHA z@Hmu4+Sl*S$6I-+Q;lQqQiu{tyJxfLLe?39N1?B$w~QY}Xo(Hn+<4h91zkLePE3rH z&;Q?C%2O>8p-1kk?Lh`Ix2GvxDFe#WLRS~aBmx={7zx8%J2(cqt?Tf>CER8$34f(G z;t_*Y#1rdHVm@4mtA{fR6rQW7yK1YGccdUs1^X?e_WnLn5h_WA9U2M2PUfQ6tDWl| zcM;vZ30x}4%d(`8i5uq)R4bX@sm~HSAH7~Y=}1J*mRK^{bHl?FBJuB$Uw)o^EGa3; zL>)dWxhR_2eh9Lf`rgLh2aNZa0C#bqF7)XWts4m9Xn<~DvQXt{=0y|)C{#}9wn-u| zYD2BZjjrG9H>~2W-yp&W)dAg~KYywb5D;L0)yIudgnlk&NFUDE=P(F~m4W9`LKuTH zODihA#7@Pkj&xH#x@ul6;iw#>_rKrA%Ya7;%oDhof`@ufZf?Y(bTl}n(>vbZqVNOY z+5E~lc{Ff5U}Vf-1+z=I)zTv|Z#|0&wdD}78kHzit%xTU(SG?jkxqtI=)kM7RpS}fwxTSfVk0#qO@nh%Z?$ce12qPP0jV9kus9+H`EVF9qpL-<8k|uv`oEzA z0RHb2eOnPj_P^Qx?o$K*Hyyo-Z4wU^^W2PHeVK9a0Y|A_WaFeMS}WlAjnHRi0K3hC zj;uXH(EceuKBHq6WA3C5Yf^xfH09&0*t2S&qN#IE8E*--FfD`QG`x&RR-^xazif@JLafDj%z>p zU$`omZ9@TBd3pKHvu8EihD*PKc)Pp1`F!@~6Hf!ZOT^hbFejvdM3`8ll@El76NiBJ zxSImHs!%fj1Kz?(wzk)#_U^H7*Z74o?BRC`P6 zpMTZY(VMvz&#ubUE+LJ|jv-oOhawJGSbI+-c-&nb)|v6ibLk01KB;PHv6SfKp0ii^ zx2@#OI-3M9p-iQ5go=QJ-ftZ_H9knxpTn+ z_*gBQT%W9fN6mTH$G=y_i6a5ic5nBubhur~cdUR|JbY^Ex!l`tS5gMg_j!f+ObYRf zi?wxiN|kag$kx}llCS*n>Rp!?stB4D^Nkgqe;tuTydt)#tvF0k{ux`XSY<4~cPbWR zRvTU0{O8*d;v2Di>BK~hl8_4xZ#pOW%Vl?Bd1f*tkY5z_@nzGvrK@X|_0{Q4S!-+S z2U%5_JCw~2&8GpnPgA6L($ou?Nn!*zIW_9Mcc$L?v^@Eak+isfPL{2GQ7K4m^|l^# zSs@UAcWm3;&^A0iPI0QKlOYg+>Dd~+Dm_mHiQsv#_u__>ghbcGghMf_Eml&e-SEbw zlKj!5N1%ITbXa`_=T~)l7!8c$pCB$!S~XlcGozntL1r7oZ`A-)!aK4QQ3#oRM{aT9I4sUWMa>%WQ}b{t1^2O}T#qxO!*^&I zF{}H!y#xsf3Cxm7_Bwr0?UL{;`Y)GC^@_STi2O}wKV11YAc}w?){)GuBUFVhC^hi% zPx}5WBElyj(c)%2?7nCw44Vsjhz&26MHRFt^R65t!)6+Z!=UShZ0alJM##PZ{8in; zNJ5X{*@x?d!00gHzcYUYb#>h1<751Tl{tl|hwtYs0th604^B-wXhfX-jCs-t(}w?m zcz-5M6Jr>&6aQq>C zvBqSU(+kd)84Qk$cngc)kYIa?g@E+_^remCY*hofnVA|8;Ck*wZd|!>04Zp1+gUPK zHMdJpMJsLE-!>qB+4>GO{QA(6oyX0bRRAG^(=E@wM9$Qg=7jJ3olN)#=3C{^=?(!n z=3nyQ_%;~}nutFjZK_a>rQ}1i*6_yp14?l&+Np`EM(zXZstoSZc87uLbdU>{Zg9Bn z#3XsNIaPEVyTT9CqGYKJJjrDRoKM5HNrpx3CrK`=k1cc`wrV^F19Lk9fx}*}ILlNf zA*e@Kq-yZh(Y0)2s9{l<4*<|2)fDCQaUwTv74mgU0ZOyo!^5?n)?PXQEgX!GaQl`x zjjF;4ABzz&sU(JLKJ5WpknMOa%ZU=mR?@|Km!5ouDEGa2e$}F>i?`y-sf5y~&P=1_ zr7BYX}yltl??p-oAYRfJg);JIcG|=vyT^C@o6QES@cJAvc>H_ z2|JNDd+!vG5QHS+WUwYJrFVi)jErc41hAz4{e z`6cMUh?(8ZW=z?+r0A~Ui$h7xCSk9lq!iJW=~3@D+4!Y#v75m2S(l&}GGtlXy>=mX z=;Vj&;InWgVQ@|Uj5m33*ZtU*yIJwwwv)s~$1Z2m{ZUdrXbmqNk>TWhB2^dqwfaKE z76)K!_73_(`0bvuc`N=&!^jK=SSD8Ay)qx01WgLQ7&B+IeD~@+C4YdU+WNRc=#R|Z z=i2TihvT=dZ4rvct*HU!coNr%nxBPmD*k4UZf%L%N`d#Gp-_vr)YR1exj${2gANg0 zx?lAN2M0T+bz}&Dn%~azt?vZYH8hTHFIH`Ke^v5jj^0v5>Rlhshh0hTFZ_rzntQCI z7n*Cw(;zb-vAXu*<+s=QWo1MA=V+BcaUu*13`)z&(EkDrzH8&EsgUf`85_d-32a>Z z`Bk@MOpxdlyEHqIB8u8Ty{NcfSk$qpsfnykg>+68u&k}Bs&Zu*yNedKbdP_S%h<(g zHi&cIvV7S?D8rnt(;B^kQN))~jeJ#4YFq&yefhc&C%X6OcEF}+!a+#Q&d$#D-d<5L zyUX@tp6Q(GjD?G$i#hj0+V<#^bl7G#^<+s0F}T&wNy#@7*&dczb5{6VGgE|nXCy;V z^xyjwfKuX(vg3Fej~-h|NKNeqLrm;J|IA#{gPJI&a0bL_K!D=~Bwiy!q;T6#jUr2U zf#}_w@gQSC^KTl{!=o}IfV5aUb0tMpLC@Z?dm=m_e{ZQMvuSd3h-C(V;Tj`z3)nP2 zgF-Pt=UBEx{-nc)?HrrlzOgr=*0T z^U`BUKcaw(gT5r0yJ*+t=C_4!u0;G`_g)Hl?acr)2~PEi^DqzmiG&Yk5ni4~I!{?y z8An)&OUSPl2iTG%F+39|N0PD2(B07y0(!{eA!>;H!AAdqdekOADK zK+yzF5>iqFiw_Vi%bt#p-p7>0(WT>^yoRB1Mw9>vTh9{)Z5l1BH&8Ca&M8b|7kD4O zab}f@+7io`o830;FDNSv*Mt|L;e+md&XH@oUSjXAB&#fhU#W&Zd5TA%k@92(tT)10C7Tdo)A>C?E3 z*zS|_t!`7=as8a-!(-e9;}#WFGI}$r+E%L@ z?9~Qal#P*=XlXk255keKopA<5Xp|GES;FJ6C+GmdSG_Rhd|g#fPftF#70K4KU#9fo z2(&`=%vpj7HUo+IRaFl$u<>Psf`S?q8F$v=0{_i?rNx>xnuF6Q6e;*Z{NkXP>$h={ za0lRf44b16^`nyUi63%b8do9(nUO}SNsn%qmdw<1rKppK<^F7~On`BA-|o)*rHUpU zqN^REom}BWa=s7TuE*Z}4*!%xGNS&zXA09hCXYTp%R&aml>q;#ZY4nai3<}S!ffGL zwaq26Hn#TY@7rsGKm+51awBd^4>zgEx57{ctr{VLQfVD40lmC8xaKW-oeAT1GybQuT<&Cpt% zYyn!8AfaowaYO|0ylyQSfj@RKcRXWkDv|z1TCaZel88eo~ zzy!o~iV!9C1n3}CR##VN_*P+BcJ>+PSej)|JI0(WEF$IJhVKnIK~p^9n8j+9Hm^Mg z&ewTM_(GQr_~DN`mLoO1`+4Rfl#KSU<9#ZdM90lYSw(Un;~Ni!=7>nf&C5Q9jta|$ zB@;`TOx|1}%_g+rHed)SQ^jlltDR3Ne$tejlH1X;1Ud?MUXJ86l38bev~RBy*c|C= zCO6Aw61QHcD3L#wS#Dgi6&Q8ho=ab7^0F_lGqMay+goZP#lpgBEr)h`04l$#%q1iR z1fJuFbt7m*U3**KouC)I__aNn%Ng6_i01ohI<)@mKkq=EIzV+egoR2OE;#dhcmJhMZ z3n|ZlD#5LNBl5~VbSV(BFv-Z|&ei?;7a(USv)vdBCIH>@tn-B}YPcD@95bY{ytsU< z%!6YS=QyD#m>`7MoFy{u{B`>QZeC`nJSrQfj@0xMPEMkWYSar-NlveT0frA2|>-0`(?Vf-d7~{Vd z6~f3o^F;6U-J|EO=L{7nuhv&`AR-ZJH5~4LSA_%D7D~56S1(!1RIRASbtDg~EL$#b z#n`t_3d`W&U^Q>%2o(~APN3!`Rrt`8hOb?U6Show`?5P85_|X|)eHfbmzOM3Eie4o z)MDT0s9HPIJCtH*5|FK96V1Dj*^*#6RtuC~&BoT%uA$&K$xY7SlQ z1tRqvZi$ChNs5>j>1C-c}UdiZ$apMp*s%>Te<&$)fIPb>hl%4#e;5V#7 z1ja6yKGey&vd;x3bT!sMl~F!Z=1*AyPtbmLgXNAh7yD{;9kpCdNF>XQpr4+|YZtS7 zWxbcUJT%XL0ru2`boE7=LMAlSGr&2{=Ayl*XsJ${_z%7I!z+11f~$jTbA7lI232pmWM zcD}P$Qc_x7>xmke7UIUk!I29NmhMlWc@WnZ+TX7XrlzIMqOI!fqO%Ct%@>a&X%B2Z zWrh*ldf~?yz7I>B$LdUgVulUmHeo0(VPeY$_}#g-60UnncO5^MRK`Rp1EJh^6}1~A zE38Wb`GM`8knrOSu5f{uvdkn_mR}32bG1-jr`I|Zy>kwSZhezRYpH`h#(VX=f4D^CxO|v@zW^(m7mKj@0U@DM4OShly}IMKc0Y%V z;VSd_Tz5B7K+ynX~>QgJ7*#4+3@5-9w>7m zTP!&>fb&|vGaL1SOzA^P3Iss2F-9__cc367=0SulKfoEi;k-d<#@`jVZe$N3l~#7JFy|}Y8s1Z z@F)kp=^X@>jylu`09u<{thT?V ze}XO&qx5U}`FGe^IH6>$)aw+hXtT9Wjdgb@d@}aQqfL80T&B&!a-ERQ+T>SlEv>4y zc7K(53)`>qbpyJ4{C^VDSe=i6Yi9z2f7M3qpQmRg_y*X2g#kC4)x=gV&br8V_dgzM z*z}kI*K5YCoouPm#XD{e3#Gvzxcu*N;iTAuPU*RJdzoGt%4AQlF;*tCp+}2EQ%&ut z-{{Q`69pUw0{ou86^6UM=tQ#Y=;ZYE5vSqI-0bWux>hdfauE7lVd&I0`r7HU4A}lM zFX~AR>HD0VmDlp~AD0+|bFpP>q^?Ec$i$RVJ-4~>zJ;;~V{t4ciNc>yG6XKSH- z?mVGrc%@-^7au-lq@0Nf^&cC3Kxx`rjG=doPcvoo^>vayM-elL8XH_U(%PzFu}Da3 z_|4}7De&&*MV8HCATd2i%qR|R9epo<*^*fEAAj=(ggh~`*Th5wv@fy57)5c>vJ!nr z3;7S%MQ38+mJoNkhg*j3auN=?2Yt3tZZ${4I&3)l(O{b7&i9;Mp^t)}shm=62NzuM z{zv%GKyTf5syLNj=_ZsNNV?4Ks-LuheZ*j79S}T)3eE6WRt2@CJil(Pv z*?;`(1c4{PuZ9wt#T9Si`$O_hL=0iv`#wn16De zAD588!p=UY@`#)ajuL$q;`F?KQ>WWt$ZBHu+f> zE(n|vk2ul4C@!`sxZ=S}u5!n1v%C+pk;QysSWd2_^yU*E0}VU-OExypeTfsq4`HQ{ zQgdvv=#yv`j>b)bDlA$vXhrgNEDBl|-|~A}-cZi2_r(QKL%p^}81Trs+yiu!m}GmA zRA`y-NFe#Xz?%FRkQ->`v83S&ES+Y-TDl_XzV1nXUOpR26lzdz_)a1bmeV0oCzxp9 zEcdcc+N}IaV(9*3qzgDc<}mkQe?Dm-Q|S)nG2n~1@^yWt;5UcE3;UY%qD0&JV5#Yl z<4zL4Uxk+abk6-WI_6&s_4L#f8R@L=CHI~-;p*am8p(5Bx<8fi;Fw-{=*a@ zJNvDPHvuZpQs##5%~o8}d;6T+s6Q{#*Q(}QCL6pgPZR#dF-U<2y(c#J`lrVl8DhF^ ztA}F}$V2~zYO|)Pb+2(NK@r|NazXns<|Q5avqHo2Fq74;Ehh~w;~IK)%Exku80=&K zVF&C2WROAVq0#oXkKXxmTt`VAIWbUasKLR(0RTrwM+hE~!ns}38=vKaQJd+O*W zOVP@OT}w?~%dSgkl7aU6d9;Eg5vzBAqBrzk0w{Vzd%$xe{dlndpc@(1?YrYPX@OO| zJw_nf@y|HV08RNS;!%R9%lro$5e(ozNW4Cert~Cp0`0Hb0+bk@%4^}`;bA0ll+HSW zb^d3LXdGZ^iVK>XKcV5q`zyKo@87)0vL!7GTn0cvI$42!h#y&JF2eW`iNiCE5*YBt zB&y%m-tOvr{aalfTbqT>&Y6E%K>>8nSLDmc?Y?UZYmKs!vT|g8bMpdXOcrr>&Tmj9 zQQg0Yq`3rD+rzD!#hCI(s5O zQiEo*U(kf=J$h$Rp{YnH*llEB5P|+CTY$p>5JJRo5t48Vcg?mS^3G@51Ng+F*!-M# zOUSDJV}gta@ac=#*jU_Cv?E9h>HOFvNaQC{70h}sbv|$7;$!acuh%E1JsXpgSnSeC9gZNP)K7sNRUolbPnh83vU z0=vo>Hs_Y>kr~fm8*7&fUDMBCigx3OXa-!i2d(gNqtSuG{5C#^DVo-QVdGzAj#U}X z4-8IrhD!hDktMjb-w{&BD}T|< zi65Sw9UNVZ1WR&1FS6=`{kQSw4sEnHd(RGBVF%n#P(U@C(K?qp3x00~CwGsI5Q4RuZ zgjxMYe}n$Ml#hbP~Ltrnb=s$ExxZ-w)q!Vg8< zR`zNlU(oh;l{qTnCv{#Hc*+vTQsLc4S2bulj{8o&_|;+gcAX^_!E=R3YhkN|k=C(V zDTB1hhMOphRKpqP$Afs@>ZNj_G=}?d4}aNhUIFH>o}K_j)#@Mm0*PXMcY44E2uX!dV$;)gJ_SUgVS@lYPk}0?>qRUIg?c@y zqp7K1+XQj;rk9pp>GYxaZq!4giTby@?RPKDf7>IO{L`b+8)+WhPZ>UHOnB98M_(ss zE1YY+-TYjZ<7|5YqyBSJ`{{#tYDh1yWFo^*$>FpMHG*zf@?(P$COs!79^n!w1+y8z zR~*V7uJKuZAokLqc3fH#m*T{?@W3RfCMSyA9BYgXt`o9_8_d_YiowdOZ)o@&Z325U z?&q9|fX?teoMehDWjVQbC#nDvCxnbLG9()UQ(zL(4Ee1i{nc-O)@bsZy-u-CwFODs zPnZM*X7iv2mFVzib5nPtKLKPC78Wk8u6DB)YmR@2km8W7G)(z%q65Usur8o>p}w$`q~dB?_v(yv3n+%FW15-w7$0UF6@~!$id5Xbf<>zeY0AlIDN2Yxpxkg2x zN(s%tfGe3yf^XLzObngalVaoH4lUEt5tE0MHFLxt1Q3pBk#{;nTz*(L8RDr!)e3*Y zB5T9yNyCTa-GBR0G5D+&CUji=E8lWL+pCAxi<#(ymF;lzM)wf(!HMF$H70(d)9t-Z zb}i$^1_Ofg*VyeKIwFZ_Xcir>k2VJ0=jOUO@E-Ys{u^X8I56do4hf_TOb;O6$i|jS zVO#4G1{N?Ywh4ilm>7;W3pXo;d)jymgO@Kes?7in!<8!og733mZ# zgE*-aJ1}Q#oIKELqCdx$b@yXs?G_ISh2f$*2390Dlg2Ns6oGKc2brR7U_I2~Q?5|O zU4$^$(B5k1w6oHrG8&VTCbgY&qyJmGdt4=}$y}(l5O5KuN|rdXmjVH4QYZzlh34|b zU{DHyjry^$Z*jrOb3%2f7&a4s%_0uvXXTO!*k1KD#O{GMlTo@U$ze>o42CR8D=vd?VN8S5-4akQN(OK!p)r04_+umvb@tDbwJhN0J zJq`N(gz%E+&V?UN233)v%7w&|)O3 zJF{HjC*IdanO#d+RhT&Y=Dug!693&n`}H$IfIxP=!c+|oo_W04nhz+m803jIy*ovX z@wa`b020yt4Lt7gyyxZ8^D3@L3*pQoWRi!<yn(uOx3X3BEfF>V?NWxr58cShYutjiD&gmz!9R`M==oMGDFyI29D(?%{(G17a9YLAaXyIVB;IaCff4C^$EP(9sfS#3F4VW z7CI*0m>v0M=lY$I{`D4r=i%Yu_C0HCq58^UR~24;c^g!p4I~Q~?%nsi>%2`&R5&M0oHIwz$t(zTXvaM?zlP*~yhmPxkfo z3E0m;IPVApnp_*)d5UMqU$B$%{@I@r+wpGJ-S%qgercSBc`NU>v%hG$xyU=;FX97-(?|DTpC)K@H52|ybM7MV7!zb=jiQzb4lLJ$h?rV2 z^@ei)>iFRd5x4R=CX%q9%WH49n8+d^Lij{c3@z@cYJ6FcOQ09$K7+@wONHO!#UCo zvG-|P(G5u~RRjC?7a{O*ukjqIg2q^)1b|js=nqo7`~NrbWKxhEk^f(tPXPp70{^eg e2lWJTkFl0YqG=tRA*lqQFEu4?#VUEL(EkT{X6(NJ delta 8845 zcmYM3WmHse)b`H|9TL*r9YYBS2m=y=NC`-HDP6))XXq4=6p<29x}{?Pkp?j+>5^_3 znrHsc^RD&okLP?i`|P#%eP6$8H{4-;L}Mj$5<uVBa995fWZ5{IZ=M(ln77{Y~1TXmE_tQ@7>h`T>)@Q^p=W`Pe zuyf&Btj^KF-r;QccETiZ_bcqr%;6mRpU3hl7nqircOEbkUe^efrqXoij?v%EERrp^ z%$(p@lV8lC+S5d?bpi|uuT5`-ebg|oh2*c`B+$&OSuF+}kM&_X*D8zP3Otezc)<0^ zbHCY;tC5XgUq~hB?~Q(VSorMOv-C7V|NdmQ85Zz*d~3|c)|k2{>R!+HHw;{Fll>Mt zL96VD`$UUFCinh?-BaDu>$fb%u1CN~SV&qsdcOWBl9Q^r<7#Y!ufif8D-h@3+`afl zv8XMYEI}-iVD+%M&mxr!ZT@zf=;(u8bB70%=B|1Jr*7Kic4K1+c2`@m82=3t9?ea# z4xN&E^?M2|(#pH@a&T}+rA6ePbZD-(fi-qRqj?7l?pIkvtUgDXz1Bbf^s@lW!6&+m zGCug)@(2JBvF^r}JL)&uJswk7&=|E0K27J$+McX}K~SGQed3gokT6Qu;G!hNG0KQE zsZiC_Opr7?!efoU5BGHaSX-OIH^|E#PJQpEP0YS+saRb3@5_C&Vor%PFR3;rkS%F* zd2*6!^)MGHQ#XBmUMz|}ptH3BPH;SMkt5$YDAsmnAWAY@Hnwt@A>XeR?iLaxuNx4o6`gqjK#n3YvjtOwKha&AJB$ui1}EvoO{hP5*p@I8F^khJ}3 zuN9`MtnBi<>`&3Fua|g$Ly_J~Yua^~LtS&#w9Dt7QC{9_1P~Ow8gYL2oohV`Y~XwUFG?(^LL=rGve_aZ&QuUYi;RM@Q$n+S>A~v)#G? zJ}BG3O5zOQuAMT2{)($Juj64MMfFKpF&vV^D#?6iyw zjnZrbcjr`Ruu`$GF!O6k5rYr->y@ZK5FQcH{HbF;QOLBx$1r>};@r)G91+?fO4r$} zvq;tfA`plP<2r|z$H&J{yU8#2TKBi~`Tw-@r*G*N=}kW^(E0XGle;&C>*;!{nQ*n6 z+?H4Ki9_9mK#~+{>E)eF8-vf~$)@s79gLSZS)WbZVVHI4gSO{x_!vIO>npREzp4;& z?f+kbud1OBq}kWLrn*be>+0%4lH!dTUYe`_@eeB|w+aaE2Y_FJe5tv)%=NxhDZakG zU;nUNFuYO4d|iEYe_B;fFGZ4%k53RGH+|eGa7X0Y559blTXwYjG53#}vu*zdHqLt& zY?xd@S4W|s%QNf|5)dxC$D4S&+I@bw5^KbTI`7MVa^ZIxvs?Kc87jIl3DSn}`C0Xk zXem3D>bC7dnS%}#k2b&L{lwkhQrtcXr;hI}o!ow#m*;+Z+P=5Ynb&qU<2+SktA@Iq zYw}zPe)Tn=-lW3flVMq*c8*NsQcv{b5`A__NopRg4{*$+g0JpwZyurd=C0Pn$K=GZ zQ83`Qhac&=>v_a(UiIAa5M306Ln(ZwBe>O)uG@<*E*p8!Bh$%IF>6D&mHo)>H6zj{{aJKOq`uZ4=b0j+47=Y zdT|L?u`{Rip#UB)vSU2@;vYq|uK$ICn`N-mjI*_>~7*p{!y?XSGAeea~{9P<}vNMynQrgk$!{l# zV_~x-u;u>kOxMi}4{NHEre!j1UC8OOD1^vawTgPJKB>?b!*pDe z@8}2c;l_AjbOt}voPr;Gqb>5Zy)6IZN9a(75RpOXK|E$AyNL&FfBvF~;c{fJzHsaQ zCP#A;k5-wO|HN2qieiZ%?Cl7?Dpyxm+9lrs0QymNWkr2;SF=04wcu*b@9rySQ(N5Q zUK3T8d5k4y&`4-ZBJ|bv!+NqXH(lZ#Mk~;nt*J5(%1D%!<5lqSV>f+FKedAFgNI8| zPGu&~4q6d@s5N$J(_Q%5rU~mZ<;Q@pi<+lnI>p-_J4QkQCxn9ggkgt=Op(L&^AwK| z>mkX4`^&w2t_^``VG<3O`|0=D71cct7oNO&#qa;KaoVNAx8L+OGBWbxmV}ttQRQdw z^XF{UL`H%N!}#)YLAlf4&jH}euh@}nslxht%7u_Cp$3;}X!eL?!iuyxS-klK`sKgT zoR2N*v{7%bg^BE=y*mCe2xo~ql9ZN~2JNv(IFTuF9h8>x>l+y8sw@&d-q<5uy{Du8 zb!v@!#$(CzD%!2(4PF-qvaxTos%ruYq6D=EbeYS_=s^Idl?&N zjol@@si>2jrrh}3%JT{)S=dlXeMR!2cheht%WZ^KuAIDKorqTcdn_A=Y4utTs3&)Q z&@;fJo%_l1#sHYVbfm>CDJj7QUhhmn!n=}PB(D2fU!5RaoUTCeqT@=E<<!Pg}HZJ;93S9;$Vg~p`}HJm_?rP^z?L` zFp^#P-2tX&F1hr<66UnZc^tBSBC^C&Z7N79;DgUcPmEiUKla0vz$#)Qs*j5$4UwFd|A!ae|dB{=TEk4}yIJ z?YF*pt^?x04bL~!9H5Lm^WU--6Lqw;Su~MiM)NWR%5R)bu@5vt-?;(JDAQxy@KF2; zaGry8R+5&OjB|)hk6?}=Oc#(}s}asG$;$6tA~|#RBr9fz?bk_RN%AO;sDvG7;&(jy z9<~C6cjXHS2spox5+u^k@mkcs;JWtS=OXJ~1gA(D_5M}sl;Mx&VclNP=~!yRr5E?E zXq_aGT2fe@*GKWifj{R6Y6IP)zY+Iuu^pXUM8BDDk8l0JW8Ig?v^!`Kd}>f@+ebo4 zO&ynB2zX$lx^{MUY90liB|v7~4$$*~q{sip{;Q3N&?!b^{hpZk*wN8Z)7;$Ly`l)} z;9X)RuFQOUd`KhiWWVq4iMFAIg@m4E=jH8dTW}y#7lP5|E055#zevMGZ}!{KpoIXNOpaEQ znQ&TqdVytU2#s_iMUfB&UVh~j32%O`iV_AaEr5p=pvLuNK6H_;4pcFvoge&aB-qwF zbS@orunMb=<5H9+M8Z;ET?FC*0Y6MK($noveH>#_csM~zQHb6ePETo&Y}kMRMrv>V zO6|H)Ctn1lnHbss?16p1e<=T0=Cm@0Z<5oPF)CKG1!BZG*UgpayAS2xdXo6Yr{F(y z@FX6HJfYQE^b*tIlPGTQFW7p4HyA=jBl5YG!fw~bN?ERY565aeo9QEV|0Z3siUl6Y z1<~5HXGcGHakREOdyP?$LAl8L3KI&8TI=2i-x=Hm8~^Txr-K?r+%husKyqGQQhmL| zl#Arl?(6#cdRA`k?|WX&g!pWZDkhV)Z7eUI(jb2jp{kxQe<4Isae$&?k0P|?wgGrV z&;6%QpZ+E5fZ-G{r4i>F0=gQksyOu$s9JWY(G{hlzB_Aa<7x+}uu95eC$!abzzy!d z14@oKlR+H>_~2{AwDB@0{XLW?N=S+yHra<3mNv&0){4al-dH`Y(Hx%PJ#F&{dq{LD zsuxO#`$P*u|BCL~qaQchJaqHYc&f#>jQ7a$mQrL#27UIU3yz0?@^Z4mYgtlKQrI0N zkhP9uxp=OUe=P<0`J)n;WF_C)8yhGqV`Df+#24Js$NaE_lvH7Pd3nc+Dhm*EN$-0z zPGY~M10o>=dggafm5(|9@&#T)@Y?~eegZB(pw}QD@QGU6@3~~PnB>SzU!LS(oxoz1 zx;P$8%nZ!KANn*%L`}qMV3C?5^6WKPB=p>|q_rxK^xPYLHI~9zRS+tY(4Cs9w3KlO zR)N5?H;njrnt8cl6{d~26{K@Htl#@Wb4B5Qa9H{8FXI1rhSl~~JspT;W$$=8exPzo z+>@M^MhU<%n!=ivJDHtq#Y38&icsY+UopJW*~!U&9Tkd&<=%d3m}oz}-qO` z^dV%T6P7=th1vX&l+6jOg9>&>HX2=@c;ucOP$2W#&=Uyim$t)?(9Y@cX6?B|OUK0i zP;9zTDNarV7+907!-ub8Q8rs&KjhnucWo?~k)pFoUg^ptHGze}gsEn49}ekKw%PPR{>E7Em6OXuA3@*VE3u0qFy z0#&~!|NQww%q-VbP*YPgu;lSuHfJ;ghlqNL(`3q8VHgu69Nmd&&kq0U1FLS2WXc~L zCG)NfnPfn-3NL%@h={jI!B3i(9MMv&5i*CZOqFdpvVIz+WhB*mp!3mc+6VyG(jw92 zrCg*bATs^(3zLEeV{}3SF?WA45M@8@q!bgs(nS5`*9B>j-T*IU+!Np}V_(;r7oTy4 zL7kwiM^_k5AI`tm=bUg#N^?l4*C&yJQ4UQEX^-Rl5M=eyvYG;mvDX}d6Cl6fo3N6+;eD^Wv8lZOLB0n&({j3UbpEcgY&vy3SMI_Yl_qZ*57p#H zIhG!fn(p%2DcDTtXnAGDG^wP#-0st$X_E(=n7BCI(Hz;Q zl`5{2FM=5r_L%7;y;l22JLJS{9k>bQMX$ghN5|n|&fMS-%MWzo;#iVUoV<6BLpCwl z#9AoS`?gk-alX4xMqF0+g2(;NMfScLmq{1U*D3qC-Fw#D=xW_WeScxL+57LDA4d8- z+f!B?4<$sJ?1ZYTtEWWb=>S0~#b{-Q`!SM~BkGzfN`llx7(t-Po%#U&UQ6_D0bGCA zMKFm4j85-bxeD!d&jjSIek)RNbL}VkyGnVmN}Vau*Ba*OIJtr$we6g7>BbV$-1DAd z(uez@!|$?UqkS5uLp9$-Z#=#v4TZAFGLmq_#fgcynvk3XP!JN$jqy{eEXF$Kv3_lb z*}OqK2v9*o`&z7cgeJ5*FI;9^z)6nP%5Um3z40`72H5MPIZvsD%{Gp+^th1AjS1m+ zqyd2hGfWg(#K=$H?O&?Wi5Q00SF24em6TyND)etu$&{+S)&}AK$OkT317G(o#U<$& z9%`GFUb3X!J;XB2)7t(`vwMJ6Gf}_oCr8V8Ak2+M$;W-!3H7#CFv$H5lyYZ=rgY** z9^PL0MVCrn_C9X;`(9j3OoDXNjVNpC5p_sDm)$lC@bl+v-BD4|T48lHW5A8h#_8j~ zKKHP1ETmkX!>@yT( zn#N=%r`myf)&ZuMdgePAdq^>fPnh~aql_pmu~D;E(O3?KGQscxyRdPmlfVQRu~rlF z7uX-`?O!i9dNh?TWMS-wOUgkO7U9MMQodV5lIt1c72AbsNp8{oC|Q<{a4PpZ0yMF9R9O*Dc|1;`4Zy32TAID!PuTIJ zun4)dzkc~APZ?3z#?X+am<<6;8(dy`?_o$g)-TJbcK&qGO%9uBx;@Zu$^s`xOUq2zDRZS%g3iD=3mSvI(2@n&@z>VG_J?|t``jU}9-QteJ&w|L5MiTf^hZVpd{ zmkYEkv#6THouS4`1SVCm{)&e-J+acS8gjckcSG^eWeydES<~jlQ?}h+Zp+7ltNm|9 zvNVkzz^K#)wXNaH@ca_vgj3SD7QncnMHi35&dg1P_EXCrjj+w{FM{FM!Uag4;M>Up z7Vgb!2UBtG5salMaX?Zp@c^R1rO!{525NAnX;5k9%EeavCDi(xGeUcxF3FT9DO>E$ z@0iQFy^O9#~CcbFSV_pR+dIlgUXeH*clJbj0@--|d!9JXTBH zkptfA!)$#?ERBW+1_SI>rKN-h1_n$16!ic%mNfRF1QG&-U>^`6pXc`C#u-L}?|8ta zmd4s3l_LQE(gNeTg*G)cy(WZOu0K^In{J9?yhitPB>7CW6AcVz{@Krxjv-K`mc-O_ zNfvHniT$}POf?9ngbmU4gX z+;bUNQ&mb|V{7Z#Qq1^6nca1~vk>iDl5-(+8GlJyq6PIQ4??g&2ZaZDyX!x^d@_V5 z7B{=CLZ?zO7}|0WQS9tgFO~1E&r*HnK!($`OTlCF7i@4n`|93NvV`Ado1_pm9~@BF zTti+Sui~QYCrve)yw}*!&@i$Alt4mv`}5RdH2$j<#+;_$(Q{AcUZ6w0HhdT3s3@6*eHUyYD!>PB~E$y7WqU|(}n8>v$_ys z0U1z%c=stNDuVnJ9UruLu^U--qAp3}j2Vs;Kl3ck<}?X&XBe);Cf%Lb1i2Lf*I4Me`gG$_CN7A+>PUQ zzHWP#pGf3(xI;&&ca-Le0-EQeCCza_W*A&2jQW1Zht++x&%FAEhGK_@hugIE~XLQm*=l^JX2Qn5xl#dU4&p!o_$tr!iP)K zNDDWq2}nt0X36;SW2_{_;NW0}-f?FikTH0ccQjY)aG*BtY+H^nlPk}H7&m13sevA9?q5xW#uAIuDX%8 z7NHFafcV!Y#mE1`T*qb6WSA#VTq@jJlE<``3v4|AVq0EEB%kuX>zMrIwpH0BL23K; z;;<$5dcmKmTky)~y7q?iq--8fKPPn>QG&y3^7UR}NEWV{Q+G=`kB?$hXOW0Hc z<6xH*2QG)sg$fBhZ5VjtL-;)L1GVqNz_X3(lt+O7*_E7@;Kda}t%p6z!wWd*=WWrv z24;+JgHTr1*3DzbwuLsj1}`FGAMYV6dP$~steCXgKo^NHUHJIyZ~R2>P+xN8Qg)Ay zLpgS{E;R=5_Tpa!TGDUNth-T)M%XNoK-PObVdKgtwc3<`HtWajT~eM8>-L;3+0%*K zmHuzB6yz){3vPFBIn;D?bgXs-kI+Ud#QOxvg$oOrr?7AuWFHoDWPYSxQyU>X8rgUa zVddik)txchmbUGMB(MJ*5)3w>`t3)avQg9!;=12lv4>cUzx8U59&}#3zJ2ha=LPM- zk5~DX%xe!}HXGd!q+2&tSe0;iWq9hm?I}dW_N>R(a+dzSR0C_5cZ z3U*t*X8e|dxBtCON&$We-dRQmghS_Sxc|VTB=Nx+vUF2HWuCHprU8Hy$SeRZCN;?& zQmDKz1eTYV>*tvv9Si2gjQEp1^^07cMq(sbCogZJHLm3xDrO@p0A{ndP#XmKFvqmC zz6I82KiG%!uk)@qPxqn8IBJQEFPV;b9Lz~bk(6sz$Lk{`z&)arzTXOsmmnjo-K8GA z&HTdq#K`^*(I+3X$+=APcoggwrXROJCTifW#$O|bSl~a9D2x^r_nQMJeYQWPKzoEX ziyJ4yb%DLECyZvo&_w%jAu(#p$>8YPcAjL%Q2~Oh?jaBlekp>I)Igy$7!@d3?q387 zKroAf$78vVbe}&DUmMCSENi}5)4{$rzGDl3T=p=XRskLYNI?KxOY5*V1Z4P0kqSxh z*RLBUOm#(QiBl+W31agFK21@X+$k+f(Z305j6P_N>#(vQ@b~WxWW9hdARN-$ zfmrP9Kb{rtrCm`a9-_Z8+b{#v$nNKjaU$C*vpal#`j0Z7zdJa3PU^!V!8#3DtnRYf zfS}KplefabwKH&M{E+;vfY(n`gvf%hU}$M86YBo+-y>*yAo{E%C%FCJ_U@sSIq9U! z*}>{IPtqpEU%b~}m?FrE4PO18d0(?X`Dp5T(#*+y;?;37&Dn#F8fRuNZ*N^g?nihi zdoIBGZKuxsN0s>gQiHN;pG`fVHF>arT}Myv{?F#n#J8-VH}34p%`RX8RI?!Ce>S=& zFi4T$kuobMzBF!?1Lmgz1B-k1DEW}326PBtDmga$C0RRQT~HVWIU0B;%Yv5^|3(iD9s$GrX^*F0J7v;C_> zsX3Ow(_rx3h=Z@E=OMiQnIn^4uunY?t5L{ZzK|oH55YMH7#%{ZLpv*SwXrLtDP>PQ z&Cp4jy7w-kt0o+hxY*W?YYARG7-fDGf2BJACHQRGQMO$^LIY`LHxdY~%s_UETyCu? zB{~))UoL76eG3F+2r;@*eqi32TavB3paw?S=tmo;bWO#U*w4e5VWIZrGK3><%%mpw1 zP|%A^fy1k<(=O#~$NjmbUaV=NaOmKm#%JEb7-AENC-H0@NhO24wQ+Corp_l+9Y)?i z00*)SU6ih?8Oni!mA5SQCC^WdT0>k1)XsT7Z4Zx(*faYthQ2O@ei%JajTv}0F=y4S;nHa+!bgfj@F= P12CbkqNQA^WEJ*52gk5i diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 86e119f5e6f..4dab625d2c9 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -163,15 +163,6 @@ void make_local_action(bAction *act) } } -static void free_act_poselib (bAction *act) -{ - if (act->poselib) { - bPoseLib *pl= act->poselib; - - BLI_freelistN(&pl->poses); - MEM_freeN(pl); - } -} void free_action (bAction *act) { @@ -187,8 +178,9 @@ void free_action (bAction *act) if (act->chanbase.first) BLI_freelistN(&act->chanbase); - /* Free PoseLib */ - free_act_poselib(act); + /* Free pose-references */ + if (act->markers.first) + BLI_freelistN(&act->markers); } bAction *copy_action (bAction *src) @@ -200,6 +192,7 @@ bAction *copy_action (bAction *src) dst= copy_libblock(src); duplicatelist(&(dst->chanbase), &(src->chanbase)); + duplicatelist(&(dst->markers), &(src->markers)); for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){ dchan->ipo = copy_ipo(dchan->ipo); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b4512f3b1b3..54d090ddb22 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -225,12 +225,12 @@ void free_object(Object *ob) ob->path= 0; if(ob->ipo) ob->ipo->id.us--; if(ob->action) ob->action->id.us--; + if(ob->poselib) ob->poselib->id.us--; if(ob->dup_group) ob->dup_group->id.us--; if(ob->defbase.first) BLI_freelistN(&ob->defbase); if(ob->pose) { free_pose_channels(ob->pose); - if (ob->pose->poselib) ob->pose->poselib->id.us--; MEM_freeN(ob->pose); } free_effects(&ob->effect); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a886c0d195b..6381aec7872 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1802,9 +1802,6 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose) } } - // ob->id.lib??? - pose->poselib = newlibadr_us(fd, ob->id.lib, pose->poselib); - if(rebuild) { ob->recalc= OB_RECALC; pose->flag |= POSE_RECALC; @@ -1864,13 +1861,10 @@ static void direct_link_action(FileData *fd, bAction *act) bActionChannel *achan; link_list(fd, &act->chanbase); + link_list(fd, &act->markers); for (achan = act->chanbase.first; achan; achan=achan->next) link_list(fd, &achan->constraintChannels); - - act->poselib= newdataadr(fd, act->poselib); - if (act->poselib) - link_list(fd, &act->poselib->poses); } static void direct_link_armature(FileData *fd, bArmature *arm) @@ -2790,6 +2784,7 @@ static void lib_link_object(FileData *fd, Main *main) ob->track= newlibadr(fd, ob->id.lib, ob->track); ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo); ob->action = newlibadr_us(fd, ob->id.lib, ob->action); + ob->poselib= newlibadr_us(fd, ob->id.lib, ob->poselib); ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group); ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy); @@ -7821,8 +7816,6 @@ static void expand_pose(FileData *fd, Main *mainvar, bPose *pose) expand_constraints(fd, mainvar, &chan->constraints); expand_doit(fd, mainvar, chan->custom); } - - expand_doit(fd, mainvar, pose->poselib); } static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) @@ -7900,6 +7893,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) expand_doit(fd, mainvar, ob->data); expand_doit(fd, mainvar, ob->ipo); expand_doit(fd, mainvar, ob->action); + expand_doit(fd, mainvar, ob->poselib); for (md=ob->modifiers.first; md; md=md->next) { expand_modifier(fd, mainvar, md); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f1fe64eb820..87462ad78f6 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1738,6 +1738,7 @@ static void write_actions(WriteData *wd, ListBase *idbase) { bAction *act; bActionChannel *chan; + TimeMarker *marker; for(act=idbase->first; act; act= act->id.next) { if (act->id.us>0 || wd->current) { @@ -1749,14 +1750,8 @@ static void write_actions(WriteData *wd, ListBase *idbase) write_constraint_channels(wd, &chan->constraintChannels); } - if (act->poselib) { - bPoseLib *pl= act->poselib; - bPoseLibRef *plr; - - writestruct(wd, DATA, "bPoseLib", 1, pl); - - for (plr= pl->poses.first; plr; plr= plr->next) - writestruct(wd, DATA, "bPoseLibRef", 1, plr); + for (marker=act->markers.first; marker; marker=marker->next) { + writestruct(wd, DATA, "TimeMarker", 1, marker); } } } diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h index dcd4be86733..b32da691451 100644 --- a/source/blender/include/BIF_editaction.h +++ b/source/blender/include/BIF_editaction.h @@ -100,6 +100,7 @@ struct Ipo; struct BWinEvent; struct Key; struct ListBase; +struct TimeMarker; /* Key operations */ void transform_action_keys(int mode, int dummy); @@ -122,7 +123,7 @@ void free_actcopybuf(void); void copy_actdata(void); void paste_actdata(void); -/* channel/strip operations */ +/* Channel/strip operations */ void up_sel_action(void); void down_sel_action(void); void top_sel_action(void); @@ -141,6 +142,12 @@ int select_channel(struct bAction *act, struct bActionChannel *achan, int select void select_actionchannel_by_name(struct bAction *act, char *name, int select); void selectkeys_leftright (short leftright, short select_mode); +/* Action Markers */ +void action_set_activemarker(struct bAction *act, struct TimeMarker *active, short deselect); +void action_add_localmarker(struct bAction *act, int frame); +void action_rename_localmarker(struct bAction *act); +void action_remove_localmarkers(struct bAction *act); + /* ShapeKey stuff */ struct Key *get_action_mesh_key(void); int get_nearest_key_num(struct Key *key, short *mval, float *x); diff --git a/source/blender/include/BIF_poselib.h b/source/blender/include/BIF_poselib.h index 39997930569..209c386d2d6 100644 --- a/source/blender/include/BIF_poselib.h +++ b/source/blender/include/BIF_poselib.h @@ -35,19 +35,18 @@ struct Object; struct bAction; -struct bPoseLib; -struct bPoseLibRef; +struct TimeMarker; -char *poselib_build_poses_menu(struct bPoseLib *pl, char title[]); -void poselib_unique_pose_name(struct bPoseLib *pl, char name[]); -int poselib_get_free_index(struct bPoseLib *pl); +char *poselib_build_poses_menu(struct bAction *act, char title[]); +int poselib_get_free_index(struct bAction *act); +struct TimeMarker *poselib_get_active_pose(struct bAction *act); -struct bPoseLib *poselib_init_new(struct Object *ob); -struct bPoseLib *poselib_validate(struct Object *ob); +struct bAction *poselib_init_new(struct Object *ob); +struct bAction *poselib_validate(struct Object *ob); void poselib_validate_act(struct bAction *act); -void poselib_remove_pose(struct Object *ob, struct bPoseLibRef *plr); +void poselib_remove_pose(struct Object *ob, struct TimeMarker *marker); void poselib_rename_pose(struct Object *ob); void poselib_add_current_pose(struct Object *ob, int mode); diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h index 5c6c0384042..c76f0a9c66e 100644 --- a/source/blender/include/BIF_resources.h +++ b/source/blender/include/BIF_resources.h @@ -73,9 +73,9 @@ typedef enum { ICON_SMOOTH, ICON_POTATO, ICON_MARKER_HLT, - ICON_NORMALVIEW, - ICON_LOCALVIEW, - ICON_UNUSEDVIEW, + ICON_PMARKER_ACT, + ICON_PMARKER_SEL, + ICON_PMARKER, ICON_VIEWZOOM, ICON_SORTALPHA, ICON_SORTTIME, diff --git a/source/blender/include/BSE_time.h b/source/blender/include/BSE_time.h index d5cff9f5e5f..27560c09e75 100644 --- a/source/blender/include/BSE_time.h +++ b/source/blender/include/BSE_time.h @@ -35,8 +35,14 @@ struct ListBase; struct View2D; +struct TimeMarker; -/* ******** Markers - General Api ********* */ +/* ****** Marker Macros - General API ****** */ + +/* macro for getting the scene's set of markers */ +#define SCE_MARKERS (&(G.scene->markers)) + +/* ******** Markers - General API ********* */ void add_marker(int frame); void duplicate_marker(void); void remove_marker(void); @@ -45,17 +51,25 @@ void transform_markers(int mode, int smode); void borderselect_markers(void); void deselect_markers(short test, short sel); -struct TimeMarker *find_nearest_marker(int clip_y); +struct TimeMarker *find_nearest_marker(struct ListBase *markers, int clip_y); void nextprev_marker(short dir); void get_minmax_markers(short sel, float *first, float *last); int find_nearest_marker_time(float dx); +struct TimeMarker *get_frame_marker(int frame); void add_marker_to_cfra_elem(struct ListBase *lb, struct TimeMarker *marker, short only_sel); void make_marker_cfra_list(struct ListBase *lb, short only_sel); -void draw_markers_timespace(int lines); -TimeMarker *get_frame_marker(int frame); +/* ********* Markers - Drawing API ********* */ + +/* flags for drawing markers */ +enum { + DRAW_MARKERS_LINES = (1<<0), + DRAW_MARKERS_LOCAL = (1<<1) +}; + +void draw_markers_timespace(struct ListBase *markers, int flag); /* ******** Animation - Preview Range ************* */ void anim_previewrange_set(void); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index f3058ceb6e6..31a61972ea3 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -511,13 +511,16 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_ARM_CALCPATHS 2303 #define B_ARM_CLEARPATHS 2304 -#define B_POSELIB_NEW 2310 -#define B_POSELIB_VALIDATE 2311 -#define B_POSELIB_ADDPOSE 2312 -#define B_POSELIB_REPLACEP 2313 -#define B_POSELIB_REMOVEP 2314 -#define B_POSELIB_APPLYP 2315 +#define B_POSELIB_VALIDATE 2310 +#define B_POSELIB_ADDPOSE 2311 +#define B_POSELIB_REPLACEP 2312 +#define B_POSELIB_REMOVEP 2313 +#define B_POSELIB_APPLYP 2314 + /* these shouldn't be here... */ +#define B_POSELIB_BROWSE 2320 +#define B_POSELIB_ALONE 2321 +#define B_POSELIB_DELETE 2322 /* *********************** */ #define B_CAMBUTS 2500 diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index ec763ad606c..7ec81cfcf35 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -99,26 +99,6 @@ typedef struct bPose { float cyclic_offset[3]; /* result of match and cycles, applied in where_is_pose() */ } bPose; - -/* "Pose" reference for PoseLib */ -typedef struct bPoseLibRef { - struct bPoseLibRef *next, *prev; - int frame; /* frame in the action to look for this pose */ - char name[32]; /* name of the pose */ - int flag; /* temporary settings for this pose */ -} bPoseLibRef; - -/* PoseLib data for Action - * PoseLib data is stored in actions so that poselibs can easily be assigned/removed from - * a pose. Currently the only data that is stored for a poselib is a set of references to which - * frame a named pose occurs in the action. - */ -typedef struct bPoseLib { - ListBase poses; /* List of poses for an action (arranged in chronological order) */ - int flag; /* Settings (not used yet) */ - int active_nr; /* Index of the poselib's active pose (for UI) */ -} bPoseLib; - /* Action Channels belong to Actions. They are linked with an IPO block, and can also own * Constraint Channels in certain situations. */ @@ -137,8 +117,12 @@ typedef struct bActionChannel { */ typedef struct bAction { ID id; + ListBase chanbase; /* Action Channels in this Action */ - bPoseLib *poselib; /* PoseLib data of this Action (only if the action is used as poselib) */ + ListBase markers; /* TimeMarkers local to this Action for labelling 'poses' */ + + int active_marker; /* Index of active-marker (first marker = 1) */ + int pad; } bAction; /* Action Editor Space. This is defined here instead of in DNA_space_types.h */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 16ecc4b88f0..c02b353f604 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -84,6 +84,7 @@ typedef struct Object { struct Path *path; struct BoundBox *bb; struct bAction *action; + struct bAction *poselib; struct bPose *pose; void *data; diff --git a/source/blender/src/blenderbuttons.c b/source/blender/src/blenderbuttons.c index c8fb9ec7a7a..8525187dc24 100644 --- a/source/blender/src/blenderbuttons.c +++ b/source/blender/src/blenderbuttons.c @@ -1,2020 +1,2052 @@ /* DataToC output of file */ -int datatoc_blenderbuttons_size= 64418; +int datatoc_blenderbuttons_size= 65462; char datatoc_blenderbuttons[]= { -137, 80, - 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,197,144,206,103, 0, - 0, 0, 1,115, 82, 71, 66, 0,174,206, 28,233, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,189,167,147, 0, 0, - 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,215, 11, 26, 20, - 59, 43, 0,186, 29, 9, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,125,121, 92, 84, 85,255,255,251,220,217,217, 23, 1, 21,151, -193,125, 95,201, 37, 55, 40, 53,243,155,153, 6,148,154,100,101, 98,137,218,147,166, 61,101,143,250,211, 71,197,164, 50, 53,161, -167,210,172, 52, 5,115,201, 45, 81, 7,245, 81, 82,113, 47, 23, 20, 69, 4, 69,150, 97, 22,102,187,115,151,223, 31, 51, 67, 3, - 2,179,128, 91,207,188, 95,220,215,229,222,123,238,103,206, 61,219,103, 61,231,144, 30, 61,122,240,240,192, 3, 15, 60,240,192, - 3, 15,254,167, 64,121,138,192, 3, 15, 60,240,192, 3, 15,254,119,112,230,236, 1, 0, 0,241, 88, 0, 60,240,192, 3, 15, 60, -240,192, 99, 1,240,192, 3, 15, 60,240,192, 3, 15, 60, 2,128, 7, 30,120,224,129, 7, 30,120,224, 17, 0, 60,240,192, 3, 15, - 60,240,192,131,191, 5,132,246, 23,231,206,157, 35,238, 18,170, 41,150,192, 67,207, 67,175, 54,164,166,166,242,107,215,174,125, -100,249, 27, 55,110, 28,191,105,211, 38,226,169,143, 39,154, 30,234, 65, 15,158,242,243,208,251, 59,211,115, 89, 0,248, 31, 71, -245, 2, 36,143,115, 62, 83, 82, 82, 48,117,234, 84,226,169, 54,247,235,120,216,176, 97,149,215, 25, 25, 25,127,139,178, 28,253, - 82, 66,157, 3,193,142,237,169,127,235, 54, 35, 11,220, 6,169,177, 13, 34, 64,163, 2,123,145, 99,152,247, 56,183, 69, 79,255, -245,224,241,177, 0, 60,140,198, 58,122,244,232,168, 29, 59,118, 40,236,174,163,119,236,216,145,249, 88,244, 72,222, 50,118, 18, -242,216,246, 75, 62, 47, 47, 15, 0, 32,151,203,159,164, 65,196,105,233,116,220,184,113, 78,167,221,180,105,147, 43,130, 26,191, -101,203,150,202,139,109,219,182, 97,216,176, 97, 85,158, 63, 42, 33, 32, 59, 59,155, 7,128,200,200, 72,210, 16,233,118,108, 79, -125,160,245, 23, 30,209, 28, 0,112,207,104, 4, 99, 48, 89,110,170, 52, 0,128,216,216, 88,164,165,165,213,154,191,222,185,189, -249,182,119,219,186,244,227, 63, 15,252,217,137,122,145, 33,240,221,139, 48,238,216,134,242,242, 49, 40, 7,208, 75,246, 41,230, -201, 78,163,185, 20, 40, 49,230, 98,158, 33,206,165,223,141,141,141,141, 74, 75, 75, 83, 84,187, 23,157,150,150,150,249,152,245, -173, 6,105,183, 79,200,247, 54, 56,154, 4, 75,136,143,200,159,152,164, 98,222,164, 50, 80, 21, 6, 13,167, 51,153,255, 39,102, -199, 57, 20, 0,172, 12,219,118,174,111, 67,224,119,236,216,129,133, 91, 22,195,167,185, 63, 42,110,171, 49, 63,110,158,226, 49, -215,184, 31, 39, 16,185, 92,206,231,229,229, 33, 47, 47, 15,251,246,237,195,212,169, 83, 31, 87, 33,192,214,129, 72,106,106,170, - 40, 33, 33,193,188,124,249,242, 83, 0, 48,103,206,156,167,234,122,113,204,152, 49,149,255, 51, 12, 11,218,108, 2,109,162, 65, -211,150,131, 97, 24,204,153, 51,199,165,188,216, 51,255,154, 96, 21, 6,248, 71,105, 9,112, 69,248,121,100, 26,126,128, 31, 46, -220,248, 25, 50, 52, 3,139, 99, 40,254,230, 12,206,231,150, 97,236,178,117, 78,189,222,246,110, 91, 39, 25,186, 5,175,254,247, - 85,135,101, 34, 27, 57, 15, 65,163,223, 66,225,123,189, 0, 67,121,229,253, 51,134, 15,112, 6, 0, 12,192, 96, 89, 44, 14, 6, -158, 70, 0,128,222,229,189,157,106, 51,105,105,105,247,221,180, 99,144,228, 49,234, 99, 13, 49, 6, 60, 9,223,219,160, 24,208, -173, 7,121, 45, 60, 66,168,106,209, 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195, 89, - 39, 73,221,113,225,103,155, 58,145,102,150, 11,244,146, 31,168, 0,176, 99,199, 14,197,150, 79, 62, 66,220,162, 37,138,122, 54, - 2,222,198,248, 1,160, 84, 95, 6, 4, 3,255, 60,184, 0,154, 27,229, 88,243,246,202,199,141,145,213, 54,240, 60,234, 60, 86, - 10, 1, 35, 70,140, 64, 94, 94, 30,228,114,249, 99, 87,118, 10,133,101,220,136,142,142,230, 1, 80,169,169,169,225, 9, 9, 9, -133,203,151, 47, 63,237, 44, 17,134, 97, 64,211,230, 74,198,111,207,252,179,179,179, 17, 25, 25,233, 82,166,226,226,226,236,153, - 45, 50, 50, 50,170, 11, 0, 13,209, 86, 92,174,135,200,200, 72, 50,110,220, 56,126,248,240,225,247, 61,219,191,127,191,205,210, - 97,179,122, 56, 77,191, 33,221, 1,225, 17,205, 81, 88,174,198, 47, 83, 95, 70, 48, 25,128,220,255,204, 70,171, 49,173,144,225, - 2,243,175, 44, 44,171,169,141, 52,128,169, 45,124,203, 49,232,111, 85,160, 48, 33,162,206,116, 23,165, 7,176,176,235, 61, 44, -189,248,113,125,235,179, 33,152,110, 67,210, 64, 3,211,122, 16,223,219, 32,136,143,143,247, 2,240, 52, 0, 31,187,219, 42, 0, - 23, 54,108,216,160,116,150,206, 23,107,191,160,232, 82,147,136, 54, 25,165,229, 48, 75, 69, 34,161, 80, 99,148, 82, 98,177,129, - 19,248,121, 51,180,204,108, 22, 22,221, 49,125,255,205,122,227,235,147, 39,177,206,124,183, 74,165,250,183,237,255,156,156,156, - 82,111,111,111, 74,167,211,113,246,105,250,244,233,243,121, 3, 51,246, 89,245, 45, 83,161, 35,237,255,242,229,203,104,235,227, -103,111, 13,112,199, 10, 80,201,252, 75,245,101, 88,250,236,130,202, 7,111,236,120, 23, 8, 5,198, 44,143,195,182, 57, 91, 92, -105,100,117, 13,110,245,110,168,183,111,223, 6, 0, 52,111,222,188,202,255,112,193,156,221,128,130, 8,169, 77, 8, 48,155, 25, - 91, 60, 64,131,104, 1, 13, 80,150,246,204, 31, 0, 72, 66, 66, 2, 0,220, 73, 77, 77, 13, 76, 72, 72, 40,119,154,249,155,205, -160,105, 19, 76, 52, 13,115, 53,230,207,115,174, 85, 67, 92, 92, 28,178,179,179,255,234, 93,201,201,136,137,137,169,188, 78, 79, - 79,175,183,176, 99, 39,240,212,187,253,217, 51,254,113,227,198,161,103,207,158, 54, 1,192, 85,139, 64,131, 52,194,130, 27,249, -208,109,251, 23,124,222, 92,137,240,136,230, 8, 11,150,225,198,182, 27, 22,230, 31,224,103,113, 1,136, 4,206, 73,176, 13,228, - 99,107,119,233, 58,110,207, 95, 12, 67,218,250,186, 45, 4, 50, 25,140, 70, 35,114,115,115, 81,108,188,138,118, 8,175, 53,173, -213, 12, 94, 87,219, 39,182,126, 98, 77,155,233, 70,255, 34,118,253,154,119,179,159,145, 58, 24,183,211,109,176,166,239,141,137, -137,225, 9, 33, 54, 87, 78,125,190,215,214,151,121,161, 80, 88,175, 58,143,143,143,247, 7, 48,230,224,193,131,255,226, 56,206, -100,215,150,132, 2,129,192, 59, 62, 62,126,242,134, 13, 27,246, 56,228,152,115,103, 9, 75,239,148, 72, 69, 34,137, 55, 37, 36, -126,188, 64,226,197, 9, 4, 66,142, 80,224,136,144,229, 5, 2,147,128, 35, 70,157,128,213,123,139, 69,228,155, 99,123,140,137, - 73,147, 56,228, 59,206, 99,121,121,185, 70,175,215, 51, 0,160,211,233,184,143, 62,250,168,146,225, 47, 89,178,228, 31,245,109, -239, 67,135, 14,157,106,251,255,192,129, 3, 41, 13,209,135, 40, 71,218,255,226, 87, 98, 96, 44, 41,193,236,206, 29, 96,239,187, -119, 90, 11, 25, 61, 58, 10, 64, 21,230, 63,122,244,232,104, 0,100,244,232,209,209,235, 70,127,101,177, 44,182,111, 84, 37,189, - 51,152,179, 38, 7,115,214,228, 96,218,138,203,120,125,209, 31, 24,251,207,115,245, 31,232, 10, 10,156, 18, 12, 30, 22,243,183, -250,252,249, 90, 44, 1, 48,211, 52,250,246,233,211, 16, 66, 6,191,101,203, 22,108,217,178, 5, 10,133,162,242,112, 81,224,225, - 21, 10, 5,162,163,163, 43,153,191,253,195,132,132, 4,149, 51, 3, 19,195,176, 22,205,223,100, 49,253, 87,103,254, 44,203, 66, -103,208,185,244,129, 54,139, 65,117,171, 65,122,122, 58,210,211,211,171, 8, 3, 46,125,111,102,213,241,208,122, 93, 47, 33,209, -198,252,199,141, 27,135,229,203,151, 87, 50,127,145, 80,228, 42,243,183, 13,224,181, 29, 78,195,128,124, 84,140,233, 11, 62,109, - 54, 10,110,228,131, 31,211,241,175, 66, 72,155, 13, 97,147, 16, 32, 32,224,161, 74,198,186,210, 92, 24,210,214,131,231,121, 92, -188,120, 17,131, 7, 15,134, 76, 38,171,194,248, 3, 3, 3, 97, 48, 24, 96, 48, 24, 80, 88, 88,136,241,134, 25,248, 38,240,189, - 90,105, 58,105,242, 38,213,210,186,202,184, 27, 74, 89, 33,181, 48,127,167,219, 96,245,239,141,137,137,225,211,211,211,145,150, -150,134,216,216, 88,190,190,223,107,101,254, 96, 24,198,237, 62, 17, 31, 31, 47, 5,240,246,129, 3, 7, 62, 90,180,104,209, 9, - 66,136,220,118, 0,104, 22, 28, 28,236,117,232,208,161,181,241,241,241,131,235,162,243, 85,202, 90,129,128,136, 36, 52,195,251, -153, 76,230, 80,150,227,154,177, 28, 23,193, 18,210, 2, 2, 65, 48, 33, 36, 0, 68,224,199,241, 8,226,105, 46, 64, 99, 48,123, -135,250, 49, 2,170,143,214,169, 58,210,235,245, 76,117,173,255,113, 7, 85, 23,227,110,215,174, 29,218,250,248, 65, 95,116, 23, -207,247,236,229, 50,131,182, 9, 17, 11,183, 44, 6,128, 74,230,111,179, 34,236,216,177, 35,211, 38, 4, 20,104,238,160,215,156, -126, 46, 9, 25, 58, 3, 11,157,129,197,221, 50, 19, 10, 75,140,184,125,207,232, 22,227,179,117, 22, 71,204,255, 81,161, 14, 33, - 0, 70,218, 4,163,209, 88, 31,242,188, 66,161,128,205, 71, 30, 18, 18, 98,175,205,194,133,193,164,138, 38, 92,135, 41,209,225, -160, 71,155, 77, 22,205,223, 68,131, 54, 87,101,254,102,179, 25, 58,157, 14, 90,141,246, 81, 87, 11,191,101, 75, 90,213, 79,178, -252,193,122,223,173, 1,207,158,249,219, 24, 63, 69, 81,144, 74,165,240,246,241,170, 87,134, 71,191,148,192,215,118, 56,122,119, -223, 63, 23, 32, 24, 3,192, 12,157, 14, 0,240,201,186,142,243,185,101,150, 65,126,232,116,152, 47, 46, 4, 74,203, 92, 43, 64, - 43,220,253, 30,111,148, 2, 0,214,175, 95,143, 29, 59,118,224,211, 79, 63,197,201,147, 39, 97, 50,153, 80, 92, 92,108,211,202, - 42,211,135,135,135,195, 0, 64,128,155,143,164,189,212,209,238, 73, 61,132, 70, 82,135, 5,207,101,154,246,150,176,154, 98, 2, -220, 97,254, 0,224,174, 16, 16, 31, 31,223,216,202,252,167,124,255,253,247,151,230,205,155,247,210,198,141, 27,209,174, 93, 59, - 0, 64,203,150, 45,161, 86,171, 37, 11, 23, 46, 60,125,232,208,161, 31,227,227,227,229,181,150, 18,199, 19,112,140,148,101,153, - 32,150, 97,155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84, 32,240, - 22, 50,180,223,205, 51,103, 37, 19, 67,190,112,152,239,156,156,156, 82,157, 78,199,213,100,230,239,222,189,251, 85,154,166, 27, -172, 33,117,239,222,189,193,104, 9,235, 98,220,255,153,242,214, 95,204,182,224, 54,102,119,238,128, 21, 22, 6,237,146,212,106, -211,254,109, 76,191,218,239, 84, 94, 7,119,109,236, 82,230, 43, 12, 44,180,122, 6, 26, 29, 3,117, 5, 3,149,150,113,189, 87, -214, 16,249,111,175,229,219,255,127,227,198, 13,168, 84,170,135, 54, 98,164,164,164, 64, 46,151,195, 22,244, 87,205,215,207,167, -164,164,192,104, 48,212, 71, 0,224,215,173, 91,135,130,194, 66,136, 4, 2,132, 53,110, 92,133,249, 63,251,236,179, 56,120,240, -160,179,131, 19,137,142,142,174, 46, 4, 84,177,100, 56, 27,171, 64,155,104,208, 38, 19,204,102, 26, 12,195, 86, 50,127,147,201, - 4,189, 94,143,138,138, 10,104,181,174, 11, 0,246, 46, 0, 27,220,213,252,183,164,109, 1,120,160,212,202,104,172, 78,109, 16, -158,183, 8, 1,105,105,136,179,104, 80, 46,245,149,234,204, 95, 36, 18, 65, 34,145, 64, 42,149, 66, 42,149,214,187, 77,213,230, - 18,168,105, 94,188, 61,198,166,108, 5,255, 98, 4,238,245,239,133, 96, 12,128,236,229, 85, 96,238,150, 0, 1,126, 16,150,109, -194,174, 47, 78, 3, 2,129, 75,121,169,175, 43, 64, 39,176,140, 41, 75,151, 46, 69, 73, 73, 9,214,174, 93,139,238,221,187, 99, -209,162, 69,232,213,171, 23, 12, 6, 67,117, 13,205, 38, 82, 63,108,198,239, 44,131,118,215, 29, 80,155, 32,225, 50, 29,235, 44, -142,202,190,225,174,107,204,158,249, 87, 50, 27,171, 16,224,162, 59,192,247,194,133, 11, 95,190,243,206, 59, 71,186,118,237,234, - 7, 0, 11, 22, 44, 64, 78, 78, 14, 0,160, 95,191,126,248,229,151, 95, 48,112,224, 64,239,241,227,199,231,102,102,102, 30,120, -227,141, 55,198,159, 61,123,246,190,146, 13, 10, 14,226,110,220,200,101, 50, 21, 7,247,182,105,211, 54, 51,162,165,252,146,192, - 87, 86, 44, 32, 98, 29, 37, 17,233, 41,169,151,150, 22, 10,104,240,102, 1, 39, 53,251,106, 11,203,124, 78, 30, 58,215,167, 81, - 96,216, 47, 14,133, 81, 59,159,255,182,109,219, 94, 31, 51,102,204,247, 54,179,191, 70,163,161,196, 98,113,189, 27,146,205,236, -127,224,192,129, 7,107, 1,176,105,249,145,173,219,194, 88, 82, 2, 93,129,133, 9, 14,182,106,135,174, 90, 1,110,252,113,253, - 62,218, 53, 93,151, 93, 44,114, 41,243,245,101,254,246,140,159,231,121,155,143,191, 18,102,179,185,242, 80,169, 84,208,233,116, - 80, 42,149, 15,109,228,176,205,243,223,183,111, 95,117, 75, 0,159,146,146,130,110,221,186,193,104, 52, 84, 14,116, 41, 41, 41, - 46,153,235,215,124,181, 6,102,179, 25,205,194,195, 97,102,217,218,152,191, 43, 3, 9,169,193,244, 95, 57,117,177, 46, 75,198, -125, 2, 0,109,174,100,254,167, 78,158,130,222, 96,128, 86,171,133, 90,173,134, 74,165,170,162,217,185, 10,155, 27,160, 30,126, -127,148,149,150,161,172,172, 20,165,101, 74,148,150,149,161,172,172, 12,101,165, 22,141,180, 67,199,142, 80, 90,255,119, 85,251, - 7,128,158, 61,123,254,165,245,123,123,195,199,199, 23,190, 62,190,208,106,181,209,245,100,254,110,187, 3,114, 63,157, 2,209, -203,171, 16,140, 1, 16,102,173,130,121,235,116, 32,192, 15, 59,223,141,193,173,157, 55, 49,106,249, 6, 64,248,144,151, 21, 49, -222,130, 44, 92, 6,157, 78, 7,163,209, 8,189, 94,143,172,172, 44, 44, 91,182,172,198,228, 94, 94, 54, 11,202,117,119,152,183, -187, 90,181,125,249, 18, 39,175,235, 35,100,184,218,103,171,208, 73, 75, 75, 35,177,177,177, 54,230,239,182,101, 66, 40, 20, 18, -134, 97,170, 11, 5,112, 53, 22, 96,195,134, 13,215, 98, 99, 99,187,111,220,184,113,240,209,163, 71,125,135, 14, 29,122,210,198, -252,173, 10, 36, 36, 18, 9,127,235,214, 45,209,222,189,123,219, 7, 6, 6,158, 26, 48, 96, 64,110, 77,180, 94,125,229, 85,174, -109, 68, 59,109,191,126,253, 98, 46, 93,250,243, 25,141, 78,219,152,103,204, 12, 40,152, 25, 19,101, 50,153, 76, 6, 13,138, 52, -156,201,168, 45,204, 47, 98,118,237,222,147,212, 40, 56,164,152,166,245, 14,213,247,154,180,255,242,242,114, 33, 0,248,249,249, - 61,182,110, 1,170, 54,237,127,203, 39, 31, 89,164,230,162,187, 85,158,185, 26, 11, 48,122,244,232,232, 53,111,175, 4, 96, 9, -248,219,177, 99,135,194,198,244,109,107, 2, 12,251,225, 37, 0,192,153,229,191,219,226, 3, 30, 22, 42, 27, 99, 65, 65, 65,165, -182,111, 99,250,118,149, 11,173, 86, 11,163,209,104, 55,136, 60,188, 60, 78,157,106,137,253, 48, 51, 12, 46, 93,186,132,179,103, -206,160,123,183,238, 48, 26,141, 48, 24,140, 48, 26, 12,248,241,135, 31, 96, 75,231, 76, 71, 79, 78, 78, 70,167,142,157, 96, 54, -155,113,237,218, 53, 48,102, 26,133, 5,133, 13, 90,166,182,107,235,154, 5,182,181, 11, 28, 91, 0,204, 38, 48,172,197,236,127, -226,196,239,208, 25,116,168,208,106,160, 86,171, 81,174, 82,161,188, 92, 89, 47, 65,204,102, 9,112, 83,251, 7, 0, 28, 57,114, - 4, 90,173, 22, 90,173,198,122,214,162, 81,112, 48, 58,116,236,136, 43,151, 47,227,240,145, 35, 46,211,180,105,255, 66,161, 8, - 94, 94, 94,240,241,241,129,175,143, 15,124,124,188,160, 44, 87, 70, 39, 36, 36,100, 58,213,231,234, 97,234,175, 13,231,115,203, - 96,190,184, 16,101, 56, 6, 50,114, 5,200,128,127, 33,247,211, 41,120,113,249,247,144,138, 40, 64, 36,180, 28,238,112, 29, 55, - 93, 1,133, 47,124,133,160, 77, 47, 64,175,215, 35, 40, 40, 8,229,229,229, 40, 47, 47,199,241,227,199,113,247,238,221, 74, 51, -113,101,250,194, 66,188, 27, 40, 67, 35,175,146,186, 52,224,104,123,166, 26, 27, 27, 27,101,247, 44,170,218,179,104, 23,251, 5, - 95, 7, 3,111,136, 25, 5, 46,107,254, 53,125,111, 90, 90, 26, 73, 79, 79, 39,245,252,222, 42, 66,128, 59,204,223,134,143, 63, -254,248,194, 75, 47,189, 52,126,233,210,165,237,207,159, 63, 63, 64, 38,147, 9, 94,124,241, 69, 34,145, 72,192,113, 28, 25, 57, -114,228,133,153, 51,103,118,235,210,165,203,206,201,147, 39,191, 62,121,242,228, 90,125, 81, 9,211, 18,184, 63, 47, 95, 59,213, -165,107,183,215, 78,157, 60, 57,118,231,238, 95,151,100,159, 60,217,248, 82,206, 21,233,181,194, 92,254,199,149,155,101, 75,147, - 63,237,116, 96,247,238,228, 54,173,219,236,242, 9,243, 62,178, 97,195, 6,214,217, 18, 29, 58,116, 40, 78,157, 58,213, 35, 37, - 37,101,161,209,104, 20, 45, 90,180,232,179,157, 59,119,142, 43, 44, 44,124,232,140,195,169, 58,170,237, 65,240,205, 60, 40,129, - 74,237,223,134,193, 33, 33, 88,129, 43,206,107, 29, 86, 19,255,149,211,151, 16,208,190, 17,134,253,240, 18,118, 76,220,174,176, - 73,111, 54,230,111,211,254, 93,153,101,240,203,210, 30, 13,195, 97, 9,193,229,203,151, 97,107,172,213,205,203, 34,145, 8, 34, -145, 8, 37, 37, 37, 24, 57,114,228,163,168, 39, 34,151,203,249,148,148, 20,244,233,211, 7, 70,147, 9, 6,163, 1, 70,107,112, -147,193,104,113, 3,172, 94,189, 26,137,137,137,142, 6, 19,126,249,242,229, 96, 89, 22,167, 79,159,129, 72,104, 49,219,182,109, -219, 22, 55,243,242, 80, 88, 88,136, 77,155,126,198,184,113,175, 2, 0, 95,205, 18, 80,235, 0,148,154,154, 42, 6,192, 36, 36, - 36,112, 53,105, 64,174, 76, 85,180,105,254, 89, 89, 89,208, 85,232, 43, 5, 48,141, 86, 3,141, 70, 13,141,198, 61, 23,128,189, -246, 63,110,220,184, 74, 11,128,171,130,192,184,113,227,170, 92, 71,200,229,232,208,209, 18, 20,119,229,242,101,220,180, 90, 60, -198,141, 27,231,114,212,126,255,167,251, 67, 34,150, 64, 38,147, 65, 42,149, 66, 34,145,160,168,168,200,105,230,111,167,237, 55, -104, 3, 28,187,108, 29,126, 1, 48, 98,233,255,129, 79,155, 13, 18,151,140,243,185,101, 32, 65,129,184, 94,160,177,104,255, 46, -186, 0,236,250, 31,177, 9, 2,246,215, 14, 97, 48, 0, 2,139,178,247,151,121,223,194,232,205,102, 51,190,249,230, 27, 12, 30, -252, 87, 92,216,193, 73,225, 64,177, 30,237,247,148,163, 71, 72,203, 26, 73,214, 16,229,110,239,242, 84, 56, 72,235, 44,195, 38, -245,176, 40,212,101,141,112, 89,144,120,208,223,107, 21, 2,234, 61, 11, 96,233,210,165,155,102,204,152, 17,114,238,194,133, 56, -131,193,208, 77,161, 56, 36,147, 72, 37, 66,138, 80, 56,116,232,144,111,167, 78,157, 54,196,198,198,254,107,236,216,177, 14,181, -245,204, 67,251,185, 81, 47,141, 58,220,189,123,207, 57, 52, 99, 26,113, 61,231,218, 18, 46, 47,151, 1,192, 75, 65,153,187,182, -105,159, 22, 26, 26,178, 71, 32, 20,255,248,239,121, 73,244, 23,139, 62,119, 88, 75,125,250,244,249,124,232,208,161, 0,128,146, -146, 18, 28, 56,112,192,239,187,239,190, 91, 2, 0,167, 78,157,234,211,185,115,231,125, 79,132, 0, 96, 91,248,231,217, 31, 55, - 58,210,236, 93,153, 18, 72,182,205,217,194,247,154,211, 15,193, 93, 27, 87, 50,253, 74,115,234,197, 34,156, 89,254,187,171,102, -171,134,154,147, 74, 0,240, 29, 59,118,196,197,139, 23,171, 48, 22,149, 74,149, 11,160,181,139,210,252,131,180, 4,220,247,155, - 63,254,240, 35,140, 70, 35, 76,180, 9, 52, 77, 99,249,242,229,117, 45,146,195, 47, 95,190,188,242,130,227, 88, 72,101, 62, 48, - 24,140,184,124,233, 18,132, 34, 17,204, 52, 13, 47,111, 47,108,218,180, 9, 2,129, 0,113,113,113,120,246,217,103,249,178,178, -218, 3,188,150, 47, 95,190, 47, 33, 33,129, 78, 77, 77, 13,181,149, 77,181,117, 0, 92, 50,109,206,153, 51, 7,199,142, 29, 67, - 69, 69, 5, 42,116, 58,104, 53, 26, 43,243,215, 64,171,209,162, 66, 91, 1,157,221,128,239, 76,217, 69, 70, 70,242,217,217,217, -149,218,127, 77,211, 0,157, 93, 4,200, 58, 23,191, 74, 93,216,152,190,205,247,232,202, 42,133,182, 21,254, 0,192,199,203, 7, - 82,153, 20, 90,173, 54,218,230,218,113,131,249, 63,144,249,218, 54, 33, 96,204,210,239,192,111, 5, 26, 77, 74, 69,230,123, 49, - 24,152,244, 19, 32, 18,193, 91, 90, 63, 63,103,117, 65, 0, 0,198, 29, 27,231,224,173,123,232,186,207, 11, 69,191,234, 81,190, -248,175,187,102,179, 25,131, 6, 13, 2, 0,132, 7,202,240,223,212,230,248,116,217,109,124,117,198,224, 72, 35,182,159, 22,135, -218,254,183, 75,155,233,198,152,213, 80,115,235, 27,194,231,255, 32,191,183, 82, 8,104,136,246,247,229,151, 95,126,249,198,164, - 55,246, 62,213, 59,178,143, 86,163, 9, 98, 88,198, 20, 22, 22, 86, 18, 30, 30, 94,164,209,104,206,143, 29, 59,214,233, 65,225, -215,237,191,114, 0, 54,189, 54,225,173,172, 1, 3, 7,110,151,201,100,254, 4, 60, 71, 8, 1,199,241,106,131,174, 92,113,245, - 66,190,214, 91, 34,118,106,156,183, 49,127,192, 18, 72, 93, 61, 80,111,217,178,101,255,122, 34, 4, 0, 43, 83,119, 88, 97, 59, -118,236,112,185,177,158, 89,254, 59, 15, 0, 54, 65,192,142,241, 55, 36, 67,119,187, 35,117,237,218, 21,167, 78,157, 66, 73, 73, -165,137,176, 53, 0,216,152,223,196,137, 19, 31,117,125, 85, 41,163,148,148, 20,254,181,137,175, 97,245,234, 53, 86,159, 57,131, - 57,115,230,212, 57,125,201,197, 21,244, 44,154,211,193,131,142, 54,155,232,184,124,249,242,107, 9, 9, 9,197,169,169,169,130, -132,132,132,202,128, 64,235,180, 64,167, 7, 58,155,198, 60, 96,192,128, 6, 47,187,200,200, 72,222, 94,139,183,143, 1,112, 99, - 5, 64, 2,128,223,180,105,211,125, 90,190,213, 66,224,114,123,222,180,105, 19,113,213, 98,224, 12,234, 50,253,187, 42, 44,140, - 93,182, 14,176, 91,248,103,200, 71,127, 77, 71,214, 53, 84, 69,217, 89, 0, 28,173, 4, 88, 56,160, 16,133, 0,122,125, 26,136, -197,167,219, 33, 4, 64, 73,174, 14,109,218,180,177, 48,141,197,129,120,238,169, 16, 68, 60,151,227,172, 70,236,180,123,211,154, -150,184, 59,222, 52,208,152, 87, 47, 90, 15,233,123, 27, 12,235,214,175,187, 6,224, 90, 67,209,251,241,167,111,243,208, 0, 81, -161, 13, 25,152,103,197,172,135, 81,158, 15,123, 51, 32, 50,122,244,232,168, 29,203, 31,203,189, 0, 8, 0,254,169,167,158,194, -158, 61,123,140, 86,166,207, 1,240,122, 64,150,135,122,195, 22, 36,152,152, 56,141,183,106,254,143, 36,111,115,230,204,105, 89, -147, 89,210,110, 26,161, 43,218, 14,121,192,117, 92,153,159,250, 46,251, 91,219,170,124,174, 50,113, 71,107,251, 55, 4,234,227, - 18,152, 59,119, 46,110,220,184,209, 96,121,113,102,121, 95, 87,113,230,131,114,156,129, 37, 48,116,112,172, 12,191,157,104,135, - 48, 47, 31,252,153,125, 15,237,157,100,254, 78,180,191,199,117, 57, 92,242,128,222,245, 44,207,238, 28,154, 54, 48,189,228,135, -149,241,135,190, 27, 96,117, 11,131, 27,150,132, 7, 46, 4,140, 28, 57, 82,250,132, 53, 64,183, 52,251,134,250,237,212,212, 84, -219, 10, 53, 76, 66, 66, 66,125,167, 50,121,208,240,204,191, 94,117,145,148,148,212, 32,117,153,154,154, 42, 76, 24,152,240,192, -219,197,145, 52, 3,142,164,229, 60,246,125,214,211, 50, 61,120,228,141,208,221,125,132, 61,240,192, 3, 15, 60,240,192,131, 39, - 23,148,167, 8, 60,240,192, 3, 15, 60,240,192, 35, 0,120,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, - 15, 60,240, 8, 0, 30,120,224,129, 7, 30,120,224, 1, 0,156, 4, 80, 98, 61, 63,145,168, 50, 11,224,220,185,115,110, 71,166, -214, 20, 76,232,161,231,161,231,161,231,161,231, 36,189, 58,167,137, 62, 6,244, 60,245,235,161, 87,133,249,159, 61,123,118, 24, - 96,217, 96,146, 16, 98,124,220,190,215, 99, 1,240,192, 3, 15,224,239,239, 79,249,251,251, 19,127,127,127, 17, 0,193,227,150, - 63,219,190,243,118,251,207,215, 23, 53,173,143,239,193, 99,132,255,251,191,255,139,122,194, 63,161, 15, 0,219,178,195,162, 39, -245, 35, 60, 2,192,223, 28,245,216,110,221,101, 12, 27, 54, 44,202, 58,232, 86, 30,214,123,127, 75,122,143, 57, 72,203,176, 48, - 2, 0,106,181,154, 83,171,213,188, 90,173, 54, 3, 96,221, 33,246,246,115, 93, 11,166,140,232, 58, 26, 0,166,140,232,250,195, -219,207,117, 93, 3, 0,115,198, 60, 69,230,188, 28, 41,122,123,120, 23,183,214, 20,177, 95,138, 54, 45, 45,173,202,230, 59,245, - 97,254,118,237,190, 33,215,218,175, 47,205,134,166,247,196, 50,255, 61,123,246, 40,254, 6,159,194,160,225, 86,116,172, 21, 77, -130, 37,164,109,227, 80,170,133,188, 25, 9, 11, 8, 22,120, 75, 68, 13,246,123,194,191, 73,155,162, 0,200, 96, 49,199,112,240, -160,138, 0,224,196,222, 42, 38, 0,146,250,254, 84, 70, 70, 6,146,147,147,171, 44,255, 55,107,214, 44, 91, 71, 39,238,208,227, - 54, 7, 86,173,232, 87, 50, 30, 23,122,143,125,213, 71,120,203,248,136, 86,114, 0, 64, 17,205, 76,104, 44, 22,254,100,123,120, - 69, 83, 33, 41, 42, 45,165,157, 33, 52,121,120,151, 28,150,229,195,159,238,223,200,175,125,251, 1,251, 37, 18,234,214,180,164, - 62,255,254, 15,185,136,123,106,253,255,137,132,228, 87,128, 92, 2,208,217,213, 76, 86, 95,138,182,158,203,205, 86, 97,254,118, -109,223,221, 65,154,184,120,255, 97,211,123, 98,153, 63,199,113, 32,132, 96,240,224,193,252,145, 35, 71,136,139,117, 44, 6, 96, -110,136,252, 4, 5, 5, 77, 81, 42,149, 95,187,249,186, 4,128,209,206, 18,208,160, 24,208,173, 7,121, 45, 60, 66,168,106,209, - 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195,217,250,254,134,179, 2, 64, 8,128, 72, - 0,217,176, 4, 61, 60, 78,240, 3, 48, 20,192, 24, 0,219, 0, 28, 0,160,105, 0,186, 63, 3,120,181,129, 24,236,163,147,140, - 40,135, 70,158, 62,214, 14, 21, 10,160,216,221,129,119,230,204,153,104,209,162,197,125,219,133, 38, 39, 39, 71,231,231,231, 43, - 86,174, 92,233,202, 32,204,175,159,238,141,248,129,247,111, 46,195,109, 14,196,134,255,210,152,180, 74,247,200,232, 45, 95,190, - 60,234,195, 15, 63, 84,196,197,197,225,231,159,127, 38, 0,240,206, 59,239, 68,173, 93,187, 86,209,162, 69, 11,112, 28, 7,131, -193,128,168,168, 40,108,221,186,213, 33,205,117,203, 63,139,106,255,225, 22, 69, 70,175,102,209,243,179,211, 51, 1, 96,205,194, - 53, 81, 87,231, 51, 10,182,133, 31, 52,156, 55,202, 13,126, 40,246, 63, 21,125,242,198, 39,153,142,232,181,106, 22,214,184,133, - 88,118,119,250,180,137,166, 48,153, 88,172, 81, 26,200,242,239, 54,254,244,209,212,215, 16, 40,147,241, 70, 51,203,127,178,250, - 59, 83, 81,105, 41,105,220, 56, 88, 88, 84, 84, 86,107, 35, 57,179,237,229,182, 59,118,222, 14, 24,240,116, 72,114,207,222, 65, -162,245,235,175,203, 67, 26,201, 74, 63,127,239, 68,242,140,151,122,176, 79,247,111,148,149,115, 77,155, 63, 41,190,245,200,111, -246, 95,172, 15, 83,172,175, 38,197,215,100,241,170,167, 16, 80,219, 59,238,230,181,161,233, 61,177,204,127,214,172, 89, 24, 60, -120, 48,255,223,255,254,215, 29, 82, 52, 44,102,119,166, 1,178, 85, 20, 20, 20, 52, 70,169, 84,110,115,227, 93,127,171,210, 25, - 8,224,110,124,124,124, 0,128, 41,214,107, 27,238, 1,248,117,195,134, 13,185,206, 18,253, 98,237, 23, 20, 93,106, 18,209, 38, -163,180, 28,102,169, 72, 36, 20,106,140, 82, 74, 44, 54,112, 2, 63,111,134,150,153,205,194,162, 59,166,239,191, 89,111,124,125, -242, 36,182, 62,109,199, 25, 23, 64,115, 0, 63, 0,136,177,158,155, 63, 70,109, 42, 24,192, 38, 0,207, 3, 56, 14, 96,132,245, - 58,184, 1,104,191, 2, 39,252,165, 15,211,196,254,128,208, 15,192, 85, 0, 17,238,104, 35, 54, 19,186, 61,243,159, 53,107,150, -194, 78,243,175,124,230,140,185,221,150,198,158, 89, 83,175,148,131,122,165,188,242,218,246,236, 81,208, 3,128, 19, 39, 78, 40, -164, 82, 41,178,178,178,238, 19,182,242,243,243, 73, 65, 65, 1,233,215,175, 95,244,238,221,187,157, 42,195,198, 39, 46, 41,120, -169, 8,221, 74,196, 85,180, 97, 66,241, 88,147,255, 6,249,161, 32,142,200, 71, 92,140,102,238,188,224,208,108, 26,213, 74,206, -183, 16,203,238,190,255,238, 4, 83, 51, 31,177, 88,125,233, 24,241, 42,190,128, 25,131,218,162,105,128, 12,197,103,142,146,123, -167,143, 81,179,166, 76,164,163, 90,201,249, 14, 94,190,230,186, 52,152, 70,141,196, 67,196, 98, 74,122,252,248,221,153,167, 78, -222,233, 24,214,172,149, 57,160, 81, 51,226,235, 11,175, 86, 17, 94, 17, 65, 65,146, 54, 28,207,155,118,157, 44,214, 61,194, 54, -204,219, 51,123,219, 81, 67, 31,229,157,165, 85,237, 92,253,168, 41,221,195,162,247,196, 50,255,221,187,119, 43, 8, 33,160, 40, - 10,217,217,217, 56,122,244,168, 91,180, 88,150,189, 96,181, 0, 52, 68, 60,139, 76,169, 84,110, 11, 10, 10,122,217,141,119,205, -214,250, 50,197,199,199,135, 1, 88,113,240,224,193,127,103,100,100,188,111, 59, 14, 28, 56,176, 92,161, 80,228,196,199,199,207, -119,134,224,172,185,179,132,165,119, 74,188, 12,188, 41,128, 23,146, 80, 94, 34,105,204,137,196,141, 57, 66,133,114, 68, 24,194, - 8, 4, 65, 28, 71,252,117,132,245, 97,196,148,236,155, 99,123,132,210, 23, 67, 31,168, 0,240, 5,128,131, 0,102, 88,207, 95, -212,163,176, 3, 1, 44, 0,176,219, 90,112,187,173,215,129,110,210, 59, 2, 96, 15,128, 4, 0,107, 1,252,195, 74,243, 72, 61, - 27,133,191,245,236,221, 0, 26, 54,172, 26,246, 2,235,249,113,195, 83, 0,142, 1,104,108, 21,158, 94,115,229,229,140,140, 12, -133,189,217,127,214,172, 89,138,228,228,228,232,228,228,228,104,123, 33, 32, 57, 57, 57, 58, 35, 35, 67,225, 12, 61,123, 51, 61, -245, 74, 57,174,237,153,136,107,123, 38, 86, 97,218,220,230, 64,184, 75,207, 42,228, 16,119,232,165,164,164, 68, 29, 63,126, 28, - 19, 38, 76, 64,126,126, 62, 18, 18, 18,162,106, 74, 35,149, 74, 21, 77,154, 52,113, 88,126,169, 41, 41, 81, 77,142,255,129,130, - 9, 3, 32,206, 87,227,235, 5,159, 71, 85, 87,142, 83, 82, 82,163, 68,198, 22,138,160, 38, 6,135,204,127,202,228, 87,232, 79, -102, 78,228,197,183,206,136, 3,239, 93, 36, 23,239,106, 16, 30,226,141,167, 59,133,161,169,234, 42,110,104, 13, 16,114, 60, 2, -136, 64,244,207,183, 38,240,211,223,121,243,106, 84, 43,121,173, 76,167, 92,165, 13,234,211,199, 39,185,107,191,231,205,190, 65, -173, 37, 62, 1,161,156,204,199,219, 20,212, 40,216, 24, 18,222, 92, 88,174,212, 74, 52,106, 6,229,106,147,211,131,144,213,207, -239,144,113, 58, 25, 15,112,159,230, 95,147, 80,238,130, 16, 64,106, 56, 87, 63,106, 74,231, 20, 61,126, 75,224,125,135,139,244, -158, 56, 80, 20,197,239,221,187, 87,193,113, 28,222,123,239, 61, 16, 66,112,244,232, 81, 88,182,222,229,136, 27,244, 64,211,244, - 89,171, 5,160,190,110,108, 37, 0, 40,149,202,173, 65, 65, 65,209,238,240, 79,154,166,133, 0,190, 62,112,224, 64,252,162, 69, -139,238, 16, 66,196,182, 3,128, 40, 56, 56,152, 28, 58,116,104, 94,124,124,252,116, 71, 4, 5, 68, 36,161, 25,222,207,100, 50, -135,178, 28,215,140,229,184, 8,150,144, 22, 16, 8,130, 9, 33, 1, 32, 2, 63,142, 71, 16, 79,115, 1, 26,131,217, 59,212,143, - 17, 80,125,180, 15, 76, 0, 8,183,106,252,159,194,178,219,231,167,214,235,112, 55,126,107, 34,128,124,107, 3,159, 11, 32,200, -122, 38,214,251,174,238,181,251, 47, 0,215, 1,172,177,154,131, 36,214, 6,241,149,245,126,125,246, 95, 30, 12,139,171, 99, 72, - 3,245,129, 55, 1,204,183,158, 31, 55,116, 6,176, 29,192,179, 86, 75, 74,103,119, 9,217,152,191, 61,211,183, 23, 2, 92,110, -156, 86,230,111, 67,117, 33,192, 29,122,213, 6, 88,226, 42,189,195,135, 15,131,166,105,244,238,221, 59,186, 67,135, 14,200,203, -203,171,252, 62,142,227, 32,151,203,249,121,243,230, 41,142, 31, 63,142,145, 35, 71, 58, 28, 80,140, 89,167, 64,209, 12, 84,189, -229,209,166, 14,193,184,190,238,240, 95, 76,139,227, 49, 77,190,142, 63, 60, 47, 88,113,243,184, 63,134,189,113,205,241, 0, 69, - 9, 42, 74, 46,102,113, 69, 42, 35,202, 42,104, 62,166, 71, 11,222, 95, 38,198, 29,149, 14, 37,106, 3,226,122,182,224, 41, 66, -248,223,127,221, 7,245,145, 19,252,153,109,187,110,213, 69, 46,235,108,211,105, 33,161,126,173,155,182,136, 96,188,100, 92,235, -193,207,199,249,180,234,157,240, 66,227,118, 47, 14, 11,106, 26,217, 93, 89,209, 56,198, 76,155,205, 55,114,117,126, 78, 50,127, -222,217, 45,104,211,210,210, 20, 14,102, 6,212,248,204, 9,151,156,103,118,192, 67,212,252,121,158,135,217,252,151,203,126,224, -192,129,182,254,226, 46,227, 50,139, 68, 34, 51,199,113,199,173, 90,120,125,132,128,208, 74, 73, 64,169, 84, 4, 5, 5, 37,184, -240,110,185, 74,165,146, 28, 62,124,248,181, 3, 7, 14, 60,255,253,247,223,151,205,155, 55,175,197,198,141, 27,209,174, 93, 59, - 0, 64,203,150, 45,161, 86,171,201,194,133, 11,139, 15, 29, 58,244,121,124,124,252,192, 58, 41,114,140,148,101,153, 32,150, 97, -155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84, 32,240, 22, 50,180, -223,205, 51,103, 37, 19, 67,190,112,187, 61, 59, 18, 0,158,179,106,135,246, 56,102,189,239, 10,198, 3,120, 15,128,220,202, 8, -255, 0, 80,110, 61,207,183,222,127,207,154,206, 25,120,193,226,107,137,183, 94,155,236, 14, 88,239, 79,193,253, 91,249, 58,139, - 87, 0,124,103, 61,215, 23,111, 0,152,102, 45,179,105,214,235,199, 5,109, 96, 9,154,220, 5, 32, 17,192, 84, 0, 81,158, 97, -171,118, 20, 22, 22, 42,250,246,237,139,169, 83,167,102,246,237,219, 23, 39, 78,156,192,218,181,107,163, 26, 55,110,172,160, 40, - 10,121,121,121,164,180,180,148, 76,159, 62, 61,250,200,145, 35,138,201,147, 39,215,217, 57,251,223,188,163, 40,234,219, 17, 9, - 83,167,102,254, 25,198, 70,119, 86, 7, 41, 82,215,166, 70, 89,164, 19, 96, 77,222, 27,100, 83,105, 12, 25, 60,189, 48,250,104, -154, 92, 17,253,244,167,181,214, 79, 1,205,172,248,250,235,141, 65, 91, 47, 20,222,222,120, 38, 95,181,238,248, 13,221,205, 34, - 35, 79,241, 20,140,122, 22, 37, 37, 52,178,243,203,217, 29,121,133,218,221,119,138, 84,191,220, 42,184,114,172,168,120,248,109, -147,249,179,218,104,250, 5,134, 55, 51, 84,148, 55,237, 20,249, 12, 69,147,150,131, 11,175,108, 55, 4, 6,121,203, 90,117,236, - 81,194, 51, 37, 23,136,192, 47,132,227, 56,193,189,123, 6,103,172,120,188, 45,226,223,142, 17, 87, 55,131,219, 95,195,154,158, -119, 66,195,174,212,244,109,135, 51,233, 61,120,176,168,168,168, 80, 0,128, 80, 40,196,236,217,179,145,157,157, 13, 55,253,254, -246, 48, 1, 48,153, 76, 38, 83, 97, 97, 97, 6,234, 23, 16,168,173, 98, 14, 80, 42, 83,131,130,130, 70, 57,249,174,212,104, 52, -134,207,153, 51, 39,249,157,119,222,209,119,237,218, 85, 2, 0, 11, 22, 44, 64, 78,142,101, 55,202,126,253,250,129,227, 56, 12, - 28, 56, 80, 50,126,252,120,237,149, 43, 87, 14,189,241,198, 27,125,188,188,106,102, 77, 28,199, 51,153, 7, 15,238,205,203,187, - 49,158, 53,179,141, 4, 34,153, 73, 64,164, 58, 74, 34,214, 83, 82, 47, 45, 45,242,170, 0, 37, 81,115, 82,214,172, 85,151,249, - 40,118,158, 27,197,158, 58,235,118, 0,183, 35, 1, 96, 56,128, 67,213,238, 29,178,222,119, 22, 2, 0, 31, 1,136, 3, 80, 86, - 75,154, 50,235,243,143,224,156, 95,103, 60,128,253, 0,212,181, 60, 87, 91,159,143,119,163, 76,158,129, 37,134, 96,153,245,252, - 76, 61, 26, 87,140,213,106,210,207,154,159,126,214,235, 24, 23,233, 4, 2, 8,112,226,112,213,149,210, 31,150, 85,172,108, 65, - 72,183,172,150, 30,183,226, 60,170,107,252,213, 45, 2,174,130,219, 28,136,182, 35,127,168,188,110, 59,242,135,251,162,248, 93, -165, 87,141,153,240,174,208, 91,189,122, 53,159,157,157,192,140, 1,163, 0, 0, 32, 0, 73, 68, 65, 84,141,211,167, 79,163, 89, -179,102,252,111,191,253, 6,141, 70,131,203,151, 47,223,167,209,126,244,209, 71,153,157, 58,117,138,222,178,101, 75,173,244,190, - 89,189,154,111,158,125, 17,161,167,115,160,104, 54,146,239,122,149, 81, 80, 26, 51,216,203, 21,247,165,125,255,163,183, 50, 91, - 68,158,142,190,245,199, 43,181,106,207,215, 11, 10, 62, 40,160,153, 21, 37,165, 6, 57,109, 96, 3,115,238,104,124,118, 95, 41, - 44, 51,181,236,142, 78,161, 65, 0,128,221,231,238, 9,115,139, 42,252, 0, 4, 22,209,198, 78,183, 77,230,216,220,194,194, 15, -106,163, 57,228,133, 56,170,195,224, 37, 93, 25,221, 31,249, 45, 58, 14,149,137, 68, 44,125,253,143, 12, 85, 97,254,229,123,197, -249,191,231,107,148,133, 0, 69, 17,165,150,246,159, 18,215,211, 81,187, 33,177,177,177,213,153,113,117,179,186,253, 53,172,233, - 31, 86, 52,190, 7, 13,136,193,131, 7,243,135, 15, 31, 6,183, 57, 0, 60,207,227,243,207, 63,199,145, 35, 71,108,130,154,219, -117, 80, 94, 94,110, 34,132, 12, 58,117,234,148, 49, 60, 60,124, 88, 61,173, 58, 1,128,101, 54,128,245, 60, 17, 0, 23, 20, 20, -228,140,162,102,108,220,184,177,122,223,190,125,111,110,220,184,209,255,232,209,163,226,161, 67,135,170,109,204, 31,176,108,119, - 47,145, 72,112,235,214, 45,106,239,222,189,126,129,129,129,119, 7, 12, 24,144,203,113, 53, 79, 86,107, 27,209, 78,219,175, 95, -191,152, 75,151,254,124, 70,163,211, 54,230, 25, 51, 3, 10,102,198, 68,153, 76, 38,147, 65,131, 34, 13,103, 50,106, 11,243,139, -152, 93,187,247, 36, 53, 10, 14, 41,166,105,189,219,179, 16,168, 26, 58, 6,101, 61,154,194,226, 23, 62,108,119,143,178, 94, 55, -182, 62,183,221,171,171,131,206,128, 37, 64,239,102, 53, 58,213,143,155,214,116, 51, 28,208,163, 0,140, 5,240,189, 3,122,223, - 91,211, 81, 78,208,179, 29,173, 96,137,115,248, 24,150,153, 4, 31, 91,175, 91, 85, 75,231, 12,189,241, 0,222,177, 50, 89,131, -245,158,193,122,253,142,245,185, 51,244,226, 97,137,115,112,246,136,119, 34,127,159, 1,248, 15,128, 81,214, 50,167, 0, 72, 1, -156,176, 90,101,250, 2, 72,178, 62,175, 43,127, 24, 54,108,216,125,190,126, 91, 16, 96,245,216,128, 97,195,134, 57, 20, 6,134, - 13, 27, 22, 93,221, 55,223,118,228, 15,247, 49,127,234,149,114,184, 75,207,166,101,186, 74,239,220,185,115,104,209,162, 5,238, -221,187, 71, 10, 10, 10,200,221,187,119, 73,255,254,253,239, 11, 6,172, 52, 83,121,121, 41,164, 82,105,173,244,228,231,206, 65, -213,162, 9,122,220, 59, 65,162, 11,246,144,151,238,110, 38,103,125,138,163,217, 44,117,141, 76, 62, 63,135,134, 68, 90,183,178, -115,189,160, 96, 78, 1,205,196, 20,208,204,138,219,180,249,243,115, 55, 75, 66,244, 12, 3,181,209, 98, 28,187, 84, 82,130,155, - 70,122,195,109,147,121,205,109,154,249, 34,183,176, 48, 29,117, 76,157,109, 42,239, 48, 39,160,105,191,208,210,252, 3, 90,134, - 49,149, 23, 22, 73,155, 93, 56,113,202,255,242,185,243,109,242,110,177, 61,111,223,188, 13,177, 72, 24,218, 57,204,123,188, 74, -107,110,227,168, 62,210,210,210, 72,108,108,172, 83, 66, 97,108,108,108,116, 90, 90,154,203,140,194, 62, 16,240,113,158,161,243, -119,198,144, 33,131,249,204,204,204,202, 24,135,253,243,124,193,243, 60, 6, 15, 30, 92, 31,211, 63,172, 76, 58, 26, 0,158,126, -250,105,125, 53,193,209, 45,121, 34, 40, 40,104,130,157,114,106, 82, 42,149,187,149, 74,229,186, 58,222,177,165,229, 0, 84,132, -133,133, 93,120,233,165,151, 86, 47, 93,186,212,235,252,249,243,254, 50,153, 12, 47,190,248, 34, 36, 18, 9, 56,142,195,200,145, - 35, 43,102,206,156, 25,208,165, 75,151, 43,147, 39, 79,238, 60,121,242,228, 50,163,177,230,133, 3, 19,166, 37,112,127, 94,190, -118,170, 75,215,110,175,157, 58,121,114,236,206,221,191, 46,201, 62,121,178,241,165,156, 43,210,107,133,185,252,143, 43, 55,203, -150, 38,127,218,233,192,238,221,201,109, 90,183,217,229, 19,230,125,100,195,134, 13,110, 79, 7, 20,214,160,173, 71, 2, 24, 0, - 96, 17,128,233,214,193,210,187,154,217,238, 7, 88,252,236,159,192,226, 18,200,174, 67,192,120,202,170,253, 58, 99,142, 63,110, -181, 46, 80,117,208, 11, 1,208, 18,192,105, 7, 52, 79, 91,211,133,162,246,169,139, 20, 44,129,121,129, 86,198,249, 18, 44, 83, -255,114,172,180,115,172,215, 27, 97,241,147,111,128,197,117, 65, 59,160,247, 10,128,111, 0,116, 0, 80, 84, 45,159,119, 97, 9, - 90,188, 98, 77,187,217, 1,189,247, 96,153,221,160,119,162,252,188, 0,236, 3,240,147,131,250,120, 25,192,191,173,231,179,118, -249, 19, 89,235, 50, 13,192, 42, 0,139,173,207,239,214,246,131, 25, 25, 25,153, 0,144,159,159,175,176, 69,251, 87,215,250,243, -243,243, 21,246,105,235,130, 45,205,134,255,210,149,209,249,213,181,244, 13,255,165,241, 40,232,101,101,101, 97,208,160, 65,184, -114,229,202, 95, 76, 92, 46,143,222,178,101,139,162, 85,171, 86,209, 28,199, 41, 90,182,108,201,219,166, 1,238,218,181, 11,145, -145,145,209,123,247,238,173,145, 94,251,172, 44,252, 28, 28, 90,165,172, 58, 38, 14,135,238,211,219,192,179,161,224, 57, 96, 90, -203,239,248, 10,206, 7, 74,131, 31,148, 57, 65,232, 62,104,103,244,229, 95,234, 54,179, 95, 47, 40,216, 10, 96,107,235, 22, 77, -219, 3,248,135,137,229,144,126, 33, 15,131,194, 44,238, 78,194,243, 90, 45,195, 44, 42, 46, 46,190,231, 4, 51,253,148,231,121, -239,156, 43,202,215, 84,167,183, 52, 42,190,171, 68,241, 61, 45,132,194, 50,239,138,114, 30, 42, 13,203,135,134,136, 3,132, 28, -198, 24, 76,236,207,139,222,123, 58,224,147, 47,142,171, 28, 8, 1,153, 78, 12,216,164,154,187,192, 53, 12,181, 90, 94, 14,196, -185,250,166,205, 26,230, 40, 42,223, 62, 29,113,150, 30,137, 43, 71, 61,233, 61, 9,224, 51,167, 93, 4,210, 45,147,177,246, 95, - 96,176, 78, 97,233, 99, 46,206,249,175,181,109, 8, 4,130, 16,161, 80, 88,124,252,248,241,111,159,126,250,233,250,148, 89, 11, -165, 82,185,198, 42, 88,188,162, 84, 42, 55,219,206,117,188,179, 9, 22,151, 41,111, 29,187, 43,150, 46, 93, 58,125,198,140, 25, - 77,207, 93,184, 48,212, 96, 48,248, 42, 20,135,136, 68, 42, 1, 69, 40, 28, 58,116, 72,212,169, 83,167,179,177,177,177, 35,199, -142, 29, 91,225, 40, 67,153,135,246,115,163, 94, 26,117,184,123,247,158,115,104,198, 52,226,122,206,181, 37, 92, 94, 46, 3,128, -151,130, 50,119,109,211, 62, 45, 52, 52,100,143, 64, 40,254,241,223,243,146,232, 47, 22,125,238,118, 65,214, 36, 0,252,195, 42, -225,188, 0,224, 50, 0,159, 26,222,219, 99,213,216, 99, 96,153, 71, 30, 95,135,249,191,173,181,192,156, 17, 0,202,172,233, 5, -117,208,139, 2,112,205, 73,122,215,172,233,127,169,131,222, 20, 0,147, 0, 92, 4, 48,211,250, 93,246,180, 21, 0,242, 96,241, -223,239, 6,176, 30,150, 25, 7,181,209,155,104, 45,143, 30, 86, 43, 66, 77,249,212, 88,159,167, 88,133,128,245,117,208,251,222, -218,208,188,156, 28,188,190,119, 80,126,159, 89, 45, 27,251,173, 66, 13,170,209,254, 13, 64, 39,107, 93,228, 88, 5, 41,135,166, - 93,235, 60,127, 69, 3, 45, 4, 68, 38,173,210,241,147, 86,233,106, 88,184,167, 28,143,138,222,159,127,254, 73,254,252,243,207, - 42,247,126,250,233,167, 76, 0,100,243,230,205, 0, 64,110,221,170, 26, 83, 87, 27,243, 7,128,230,127,254, 73,128,170,244,222, - 94, 50,203,194, 28,151, 89,243, 84, 61, 68,239, 23, 23, 70, 97,150,207,131, 16, 16, 84,160,146,249, 91,185,250, 61,169, 84,234, -148,217,144,231,121, 66, 8, 89, 48, 39,174,179, 87, 88,179,150,163, 56,120,181, 45,200, 47, 18,152,141, 42,190,113,168, 15,241, -241, 22, 17,198,204,161, 92, 69, 51, 68, 70,100,106, 45,211,166, 14,133,160,182, 54, 91,253,255, 71,201, 0,237,221, 17,206,204, -219, 39, 15,153,222, 99,207,252,185,205,129,216,127,193, 50, 69,127,189,130,198,207,199,105, 91, 76, 6,105,168,250, 97, 89,182, - 12, 0,122,245,234, 85,175, 5,129,108,204,223,138, 82,235,217, 81,223, 72,180, 27, 79,205, 0, 10, 0,224,203, 47,191,124,249, -141, 73,111, 12,123,170,119,228, 24,173, 70, 19,194,176,140, 49, 44, 44,172, 48, 60, 60, 60, 87,163,209,108, 27, 59,118,108,169, -179,249,250,117,251,175, 28,128, 77,175, 77,120, 43,107,192,192,129,219,101, 50,153, 63, 1,207, 89,102, 78,240,106,131,174, 92, -113,245, 66,190,214, 91, 34,174, 87, 64,107,117, 1,128,133, 37, 72,205, 25, 63,252, 41,235,193,162,246,229, 69, 89, 88, 34,234, -157,157,175,169,128,101, 33,159,186,232,237,128, 37,104,205, 25,188,230, 68,254,190, 6,240,173,163,177, 31,192,187,118,239,212, - 69,239, 7,171,197,192, 17,242,172,154,189, 51,249,115,101,190,235,215, 14,232, 61,235, 4, 61,155,181, 97,189,181,108,156, 49, - 49,145, 97,195,134, 69, 85,143,250, 31, 54,108, 88,180, 51,154,122,109,244,236, 86,234,123,220,232, 61,246,184, 81,120,215, 68, - 53,107,182,254,157, 79, 83, 38,217,238,209, 34,234, 39,163,158,219, 87,148,159,175,117,170,208, 8,225,255, 61,165, 31,249,248, -235,223,231,236, 90, 21,186,237,196,201,187, 83, 67,252,185, 23,169, 32,191, 0,158, 7, 8,225, 77, 38,134, 43,226,128, 82,218, -196, 5, 20,222, 53,184,228,143,180,154,249, 21,213,174, 31,151, 34,244,172, 4,232, 38,158, 91,172,125,208,223,200, 1,104, 34, -149, 74,239,246,234,213,235,217, 51,103,206,212,155,160, 82,169, 60, 24, 20, 20, 52, 73,169, 84,174,119,242, 21,129, 53, 31,149, -227,233,186,245,235, 50, 0,100, 52,212, 71,254,248,211,183,121, 86, 94,241, 64, 80,147, 0, 96,116,131, 14, 95, 71, 37,153, 60, -244,254,182,244,170,192,202, 72, 73,181,123,110, 55,206,199,157,222,147, 0,165, 94,255, 38,224,101, 6, 16,194,129, 47, 52, 26, -233,141, 69, 69, 37,231,225,194, 42,106, 31,127,253, 59,191,253,179, 17,228,133,233,251,178, 0,100,197,246,109,255,143,160, 32, -201, 92,161,128,240,119,203,140, 87,239,210,204, 6,153,136,146,202,132, 2,129,153,225,164,174,228, 47, 45, 45, 45, 51, 54, 54, -214,182, 15,128,205, 61,224, 58,103,173,238,235,183, 51,253,215, 35, 14,192,179, 18,160, 27,160, 94, 41, 7, 33, 4, 47,142,158, - 82,227, 24,178, 99,123,106, 67,125,107, 17, 0,210, 16,204,223, 78, 8, 88,239, 66,114,153,117, 76,165,159,212,186, 18,214,208, - 16, 27,114,142,172,135,222,223,155,158, 7,143,187, 0,160, 84,242, 74,165,114, 74,125,233,188,244,254, 62, 30, 0, 94, 27,220, -137,252,120,228,210,231, 6,126,218,170,233,227,142,119,162,117, 36, 34, 72, 36,108, 4, 66,244, 62, 50, 97, 73,151, 14,126, 57, -233,251, 93,163,109, 13,244,227,221, 9,248,123,192, 26,180,199, 2,224,198, 55,166,166,166,240, 9, 9, 83,201,142,237,169,127, -247,238,229,111, 21,164, 37,110, 42,206,143,190,178,220,221, 71,216, 3, 15, 60,120, 2, 37,126, 1,224, 37, 33,224, 56, 30, 32, - 4, 21, 6, 79,247,247,192,131,255,217,241,192, 83, 4, 30,120,240,191, 3,134, 5, 52,250,191,245,178,243, 30,120,224,129,147, -160, 60, 69,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, 15, 60,240, 8, 0, 30,120,224,129, 7, 30,120, -224,193,223, 17, 85, 98, 0,206,157, 59,231,118, 52,106, 77,193,132, 53,209,123,225,153,200,168, 46,221,218, 40,154, 52, 11,143, -214, 26,116,138,195,138,172,232,140, 67,231, 51,221,165,215,181,239,240,168, 30,221,250, 42,238, 21, 22,194, 91,230,141,219, 5, -185,209,217, 39,246,184, 77,175,161,191, 55,113, 60, 21,213,175,111, 43,133,204, 91, 0,161,128, 2,145, 18,188, 56,238, 18,113, -151, 94,194,255,203,138,122,170,239, 83, 10,127, 31, 1, 32, 4, 98,251,214, 60,199,233, 81,125,175,135,222, 99, 75,175,206,169, -102,143,251,247,182,234,245, 50,239,199,229, 62,208,252,157,253,232,150,219, 3,105,207, 37, 45,239,187,247,121,163, 66,183,233, -253,163,244,254, 13, 87, 61,237,249,161,208, 19,162,134, 41,178, 79,226,247,186, 44, 0,212,134,149, 81,104, 11,203,122,248, 44, -128,220,153,153,184,233,236, 15, 12, 31,216, 42,138,128, 67, 72, 64, 16,178, 14,159, 81,124,152, 56, 17, 3,134, 14, 0,163,211, - 43, 58,117, 24, 12,142,131, 98,198, 91, 79, 71,247,236,217, 13,215,175,223,130, 90,165,195,234,245, 71, 50,107,163,215,123,208, -171, 81, 60, 8, 90,182,105,165, 72,120,127, 49,222,124,245, 57,252,240,159,175, 0, 72,177,231,124, 1, 40, 10,138,149, 11,230, - 33, 39,231, 42,228,242,150,144,200,132,184, 83,144, 19, 13,125,205, 89,158,251, 92,119, 94, 44, 22, 67, 38,147, 33, 55, 55, 23, - 77, 67,253,208, 72,232,131,166, 45, 2, 16, 40,243,135, 55, 97, 65, 81, 20,120,142,133, 94, 34,132,250,158, 26, 99,254,147,225, -176,162,150,207,233,198,251,202,212,240, 11, 16,195,199, 91, 8,177,140,130, 80, 0, 80, 98, 33, 50,119, 69,242,102, 94,128, 97, -163, 78, 56, 93,225, 93, 95, 90, 25, 21, 30, 30,142,102,173,155, 41, 12, 70, 19, 40,137, 12, 48, 3,211,146, 79, 69, 25,244, 58, -124,247, 73, 84,230, 35, 20, 36,255, 86,243,152,159,112,184, 90, 23, 78,167,143,253,112,174, 55,128,167, 26,203,188,254, 93, 88, - 88,216, 65, 36,149,128,243,242, 90, 6, 96,109,218,178,164,138,199,165, 0, 34, 58, 13,137,186,121,233,112, 77,251, 41,252, 45, -218,104,106,106, 42,249, 97,195,134, 43, 18,177, 88,198,113,156,191,183,143,143,207,168, 23, 95,244, 2, 64, 39, 36, 36,240,143, -105,158, 41, 0, 72, 72, 72,224, 26,128,156,159,191,191,255,172,246,237,219,143,149, 72, 36,205, 10, 10, 10, 10, 10, 11, 11, 79, -210, 52,189, 4, 64,174, 27,244, 2, 2, 3, 3, 23, 63,243,204, 51,207,135,133,133,201, 79,157, 58,117,239,226,197,139,199,141, - 70,227, 66, 88, 86,136,253,223,176, 0,212,194,252, 5,222, 18,225, 83, 19, 7,182, 94,193,241,188,241,232,213,123, 95,174,140, - 82,239,159,153,137, 75,142,222, 85,222, 61,200,155, 42,148, 48, 87,168, 32,100, 41,252,113,233, 42, 94,127,125,102,229,115,138, - 2,126,207, 90,143, 70, 45,194, 21, 92,133, 6, 52, 71,112,232, 80, 86,244,234,245, 71,106,161,216,146, 63,125,226, 18,136,151, - 31,206, 92,202,199,249, 75,111,224,187,159,127,171,124,202,113,192,136,254,253,129,138, 34, 0,190,200,189,120, 25,162, 70, 1, - 24,208,175,139, 66,165,175, 67,102, 33, 20, 64, 40,244,232,214, 11,141,189,197,104,218, 72, 10,191,224, 32, 4, 74,124, 17, 40, - 21, 64, 36, 16,192,204,178, 80, 49, 28, 78,149,158,118, 88,168, 11,223,109,206,203, 4,229,240,243,242, 66, 72,163, 96,248,249, -121,129,167, 88, 48, 92, 5, 88,176,240,241,241, 66,163,198,205,144,123,165, 29,223,186,195, 15,117, 14, 74, 61, 99, 86,241,254, -190,222,240, 15, 8, 68, 72,163, 96,232,116, 58,136, 37, 82,136,140,150,197,249, 34,228, 45, 21,202,114, 21,158,121,107,125,116, -126,193, 29,148, 23,221, 66,217,249, 84, 71,194,128,211,131,196,208, 73, 67,163, 15,172, 63,144,233, 4,173, 7, 42, 4,228,229, -229,241, 0, 32,151,203,201,227, 66, 47, 60, 60,252,117,154,166,215, 3,192,216,232,104, 42,117,203, 22,119, 6, 95,203, 26,169, -118,134, 28,158,231, 65, 8,169, 60,219,238,217,210, 57,216, 73,205,149,245,228, 93, 97,254,157,188,205,204, 86,223, 0,255, 14, - 0, 32,150, 73, 65, 27,140,224,116,250,229,199,143, 28, 94, 16,251,225,220,142,105,203,146,242, 29,209,249,242,163, 68,222,170, - 97, 49,176,184, 32, 57,235, 56, 84,227, 88,212,125,200,243, 24,242,220,255,185, 84, 71, 55, 47, 29, 86,180,233, 18, 21,125,253, -143, 76,215,133,226, 88,165, 75,201,227,226,226,176, 37,246, 64,157,105,162, 15, 84,221,138,164, 83,128,229, 83,139,141, 28, 12, -140,165, 94,117,214,115,106,223, 0,180,243, 21,213, 73,111,197,138, 21,153, 31,189, 55, 59,116,244,216, 49, 62, 70,163, 1, 43, - 63,255,140, 90,189,122,181, 49, 49, 49, 49, 28,192,157,134,238,123, 99,198,140, 25,186,109,219,182, 12, 87,133,168, 73,147, 38, -241,121,121,121, 40, 43, 43,195,210,165, 75,225,235,235,139,168,168, 40,200,229,114,172, 95,191,222,221,126, 55,184, 87,175, 94, - 27,222,127,255,253,235,237,219,183, 95,223,179,103,207,203,247,238,221,107,150,149,149,213,235,205, 55,223,220,173,209,104,150, -195,178,149,187,179,136, 30, 59,118,108, 90, 82, 82, 82,176,217,108,134, 76, 38,131,183,183,119, 19,157, 78,247,242,232,209,163, - 71, 93,184,112, 33, 17,150,141,211,158, 56,156, 59,119,174,186,149,192, 57, 1, 96,101, 20,154, 3,104, 13,203, 18,135,172,206, -196,220,206,186, 86,252, 69,255,182,161, 51,159,233,212,100, 65, 99,127, 89,211,149, 40,218, 4,224,234,204,204,218, 55,169, 49, - 85, 40,209,184,205,179, 88,252,193, 88,172,183,227, 73,135,143,167, 64,167, 55, 97,228,208,153,120,122,192, 36,188, 26,247, 12, -100, 50, 9,104,150,129, 86, 79, 43,106,111,100,183, 0, 26, 24, 59, 97, 45,222,126,127,106,229,221, 17, 79, 71, 65, 42,149, 96, -251,161,223,176,231, 88, 22, 54,172,251, 10, 70,131, 9, 98,129, 16, 62, 94, 98,232,202, 10,162, 85, 5,168,113,135, 53,158,231, - 1,158,179, 28, 20, 7,158,231, 97,162, 37,149,203, 59,240, 52, 11, 86, 0,176, 96,193,210, 28, 24,182,110, 1,118,206, 91,114, - 62,208,143,129,159,175, 55,194,155, 69,160, 67,215, 54,240,245,145, 65, 93, 81,130,162,146, 34,148,171,239,193,108, 36,240,242, -242, 66, 72,200, 0,148, 22,135,240,141, 66, 63,171,217,140, 63,120, 30,207, 24,244, 48, 8, 1,177, 84, 12,131, 94, 12, 90, 47, -134, 81, 42,129,144, 48,224, 33,128,209, 80, 1,131, 94,139,102,205,154, 42,196, 2, 33,148,208, 32,148,158,128,234,107,204, 87, -199,167, 27, 62,117,216,128, 62,136,255,160,238,177, 50, 54,182,202,254,238,177,177,177,189,131,130,130,114, 8, 33, 70,158,231, -133,129,129,129, 94,185,185,185,193,214,213,221,154,186,219,144, 19, 19, 19,199,217,253, 70,148,187,171,197,213,200, 45, 9,225, -167, 77,155, 22,189,122,245,106,151,104,134,135,135, 39,244,233,211,103,201,192, 30, 61, 96,150, 72,144,156,156,204, 77,125,229, -149, 97, 41,155, 55, 31,112,241,247,177, 98,193,130,202,235, 89,243,231, 35,121,225,194, 58,175,157, 33, 91,141,185,243,189,123, -247, 6, 0,126,232,208, 86,157, 1,220, 72, 74, 74, 51,184,200,252,179,186,118,238,236,103,235, 51,222, 82, 25,238,150, 20, 67, - 83,174, 66,175, 62,125,189,118,125,183,238, 64,236,135,115, 59,167, 45, 75,114,180, 54, 59, 51, 99,201,106,225,107, 47,143, 18, -182,149,203, 57,171, 16,128,249,201,171,170, 10,209,179,166, 3, 0, 62,122, 47,209,173,237,164,221, 98,254, 54,164, 5,185,144, -120,168, 75,164,189,133, 4,231, 23,190, 5,226,215, 8,236,141,243, 48,221,248, 19, 57, 74, 29, 34,247, 22, 59,245,126,207, 94, -189,142, 78, 25, 31,223, 50,126,242,155, 1,105, 63,253,204,201,229,114,106,113,210,114,248, 46, 88,140,237,219,183, 23,166,166, -166, 82, 13,101, 5, 24, 51,102,204,176,109,219,182,237,223,182,109,155,237,122,184,237,127, 7, 2, 74,212,254,253,251, 21,183, -110,221, 66,235,214,173, 49,104,208, 32,248,251,251, 67,165, 82,225,206,157, 59,184,121,243, 38,134, 15, 31,206, 15, 31, 62, 60, -122,246,236,217,174,212,211,152,103,158,121,102,229,138, 21, 43, 54,245,236,217,115, 37, 33,228,142,221, 56, 78, 98, 98, 98,124, - 0,100, 89, 15,167,232, 37, 38, 38,166, 79,155, 54,141, 58,125,250, 52, 8, 33, 8, 14, 14,174, 60,246,238,221, 43,238,215,175, -223, 87,183,111,223, 62,241,164, 51,127,219,189,234, 66,128,176, 6,230, 31, 28, 25, 17, 28,223,163,101,208, 4, 66,136,136,231, -121, 51,103, 57,104,214,108, 52,136, 41,174,105,215,198,210, 15, 26,249,181,110,179,237,212,205,159, 87, 70,113, 71,103,102,214, -190, 91, 28, 32, 70,167,142,237, 65, 81,153,200, 81,149, 1,184, 12,117,225, 53,136,164, 18,236,216,253, 37,244,165, 44, 38,188, -241, 15,112, 28,240,226,168,254, 96,133, 62, 14, 63, 46, 39,231, 50, 56, 14, 24,217,157, 88,249, 74, 75, 24, 77, 52, 98, 70, 12, -135, 52,128,194,134,141,251, 64, 81, 64,250,207,235, 81,120,227,207,232,189,155, 86,100,214, 36,253, 0, 0,199, 3, 28,199,129, -227, 56,176, 44, 11,147,136,135,153,152, 65,211, 52,244, 94, 70,128,147,130,226, 89,176, 98, 30, 21,180, 17, 58,141,186,206,188, -133,248,152, 32, 20,202, 16, 28, 28,140, 54,109,218, 32,172,113, 95, 64, 64,129,101, 79,131,226, 85, 48,234, 24,176,156, 14, 69, -119,148, 8, 9, 46, 69,112,192, 0, 44, 91,177, 43,234,231, 31,239,167, 37, 51, 50,224, 77,165,128, 81, 2,154, 50, 67, 39, 22, -162, 66, 38,130, 80, 36, 6, 56,111, 16, 1, 65,133, 78,143,242,162, 91,200, 61,125, 12,202,252,124,112, 28, 7,138, 23,184,213, -104,190, 91,251,151,224,252,230, 59,111, 58, 30, 39,171,174,217,110, 76, 75, 75,155,251,254,251,239, 79,205,207,207,167, 8, 33, - 33,169,169,169, 63,195,178,185,147,151,187, 13,121, 74,108,172,104,205,154, 53, 27,239,221,187,135,244,244,116, 68,182,111, 47, -104,136, 14, 34,151,203, 73, 92, 92, 92, 20,207,243,138,213,171, 87,187,188, 97, 17, 77,211, 41, 3,173,109, 74, 44, 22,163, 93, -187,118,216,122,232, 80, 70, 72, 72, 8, 74, 74, 74,156,166, 99,211,236, 31, 0, 72,239,222,189,249,211,167, 45, 22, 43,187,243, -159, 67,134, 12, 41,156, 59, 55,214, 63, 41,201,241,154,251,177, 31,206,245,246, 54, 51, 91,187,118,238,236, 39,160, 40,188,251, -218, 4, 24,140, 38, 36,127,251, 45,188,100, 50, 24,141, 70, 24, 13, 6,116,239,217,163,237,111, 63,253, 52, 13,192, 23,142,172, -142, 11,103, 77,231, 0, 80,215,242,242,168,234, 12,191,122,247,116,231,195,155,119, 24, 28,125,251,202, 17,126,216,139,111, 69, -103,236,252,214, 45, 65,192,126,215, 62,219,150,182,117,221,119,132, 78, 1, 66,220,170, 96,113,120, 88, 8, 68, 51, 83,161,153, - 16, 1, 97, 96,168, 75,204, 63, 46, 46,174,200,172,211,223,153,252,238,212,230, 31,254, 99, 14, 86,175, 75,185,212,167, 87,175, - 86, 41,171, 82,188,222,155, 51, 27, 63,245,239,139,141, 27, 55, 78,132,101,215,210,250, 48,254,168,109,219,182, 41,108,204, 62, - 53, 53, 53, 23,150,109,218, 15, 58, 35, 0,236,223,191, 95, 17, 18, 18,130,158, 61,123, 50, 20, 69, 9, 45,214, 89, 14, 34,145, - 8, 65, 65, 65,104,220,184, 49,110,222,188,137,253,251,247, 43, 92,232,115,177, 47,188,240,194,103, 43, 86,172, 88,213,190,125, -251,181,132, 16, 14,192, 87, 0,158, 3,112,132, 16,178, 16,150, 53,243,103, 3, 88,232, 12,189, 21,137,137,155, 7,198,198,146, -157, 59,119, 66, 40, 20, 66,161, 80,224,252,249,243,104,211,166, 13, 22, 45, 90,132, 46, 93,186, 96,234,212,169,194,143, 63,254, -120,197,147,200,252,167,204, 93, 86,121,239,235,164, 15,107, 20, 2,106,154, 5, 64, 9, 5,148,144,225,120,173,193,204,220, 33, -132, 72,124, 36,130,110,126, 98, 68,202, 58, 15,105,141,232,183,129, 14,131,208,196,155, 31, 51,113, 64,196,135, 65,126, 94,195, - 86, 70,193,191,246,236,112, 16, 8,108, 99,182, 31,128,102,240, 15,127, 1, 6,214,136,181,169,235,240,195,198,116, 12,143, 30, - 0, 0,208,235, 1,129,176,118, 82, 50,175,246, 0, 0,150,181,223,155,166, 8, 64, 22, 40,129, 4,241,175,191,133,152,184, 56, -236,218,109, 97,100, 94,222,128,174,226,110,157,133,101,134,160,146,249,155, 25, 22, 38,141, 25,122,149, 30, 42, 51, 13,165,158, - 70,185, 73, 11,149,182, 2,229,197, 90, 40, 85, 70, 40, 43,106, 95, 66,253,221, 87, 91,241,132, 16, 8, 4, 4,132,146,128,101, -121, 48,250,124,232, 84,215, 80, 88,164,134,178,188, 2,106, 45, 11,101,185, 17, 5, 5, 69,184,116,229, 28, 84,234,115,232,219, -171,183,162, 54,154, 2, 0,148,214, 8,195,245, 59, 40,251,227, 50,202,242,111, 65,163, 86, 66,163, 86,226,214,165,211, 56,158, -246, 29,178,182,108, 64,201,245,235, 96,105,206,210,155, 4, 15,205, 13,104,219,135,155,142,137,137,233,184,120,241,226,247,155, - 52,105,162, 75, 79, 79,239,150,150,150,246, 43,128,158,214, 74,119,123,193, 41,113, 88,216, 44, 0,232,215,165, 11,166, 77,155, - 86,124,234,202,149, 3, 79,117,232, 16,213, 16,153,223,178,101, 75, 38, 0,146,152,104,209, 50, 19, 19, 19, 93,162,107,150, 72, - 0, 0, 91,183,110, 69,104,104, 40, 62, 76, 76,196,172, 89,179, 16, 18, 18,242, 88,248, 97,109, 76, 63, 53, 53,181,242, 0,128, -195,135, 15,135, 3, 24,229, 36,153,167, 2, 2, 3, 59, 8, 40, 10,111,196,196, 64,165,214,160,224,238, 29,136, 68, 66, 8,133, -150, 67, 36, 18, 65, 34,243, 66,107,185,252,243,158, 67,135, 58,165,177, 95,203,203,195,143, 91,127,173, 60,108,152,159,188, 10, -243,147, 87, 97,143,226,176,203,223, 59, 52,246,227, 40, 0,184,125,229, 72,230, 80, 11,243, 87,224, 49, 89,237,232,194,247, 95, -160,248,237, 94, 24,146, 81,130, 78, 1, 66, 8,252,130,192,148, 23, 35,114,111, 49,188,133, 22, 30, 40,112, 48, 39,235,230,245, -235,101, 95,167,254,167,253,247,255,249, 30, 95,126,251,213,173,175, 86,124, 54,255,253,233, 51, 70, 45, 94,178, 24, 50, 95,111, - 12,234, 55, 0,167, 78,158,250,254,181,248,215,220,254,102, 27,243,183, 93,239,220,185, 19, 79, 61,245, 84,107, 0, 19,156, 53, -251,155,205,102,244,234,213,139, 99, 89, 86,168, 86,171, 97, 50,153, 96, 50,153,112,229,202, 21, 40, 20, 10, 28, 59,118, 12, 77, -154, 52,129,217,108,198,164, 73,147,156,201,235,184,184,184,184, 47,198,142, 29,235,183,118,237, 90, 63, 66,136, 24,192, 97, 0, -106, 0,189, 0,252,106, 39,120, 30, 4,208,197, 17,189,109,239,191,191,121, 84,247,238,228,167,152, 24, 20,158, 61,139,207, 62, -251,140,219,181,107,215,255,187,125,251,118,168, 66,161,120,123,238,220,185, 48,155,205, 24, 48, 96, 0,188,189,189,251,227, 9, -135,189, 48, 80,167, 5, 96,102, 38, 74, 86,162, 36,229,247,235, 37, 25,145, 17,193,209,189,229, 65,150,117,196, 95, 88,132,223, -125,134,227,224, 31,197,232,223, 57, 16,207,200,119,193,247,183, 37, 61, 71,244,144, 79,216,120,228,210, 31, 53, 17,111,210, 54, -150,240,124, 1, 63,250,245,153,152, 53,253, 43, 0, 74, 0,190, 0, 76,104,217,190, 23,164, 18, 33, 12, 58, 19, 64, 91, 4, 4, - 95, 95, 95, 20, 43,107,221, 47, 27, 6,253, 85, 2,128,191,244,251,183,160,168,213, 85,148, 4,206,240, 39,140, 38, 51,100, 62, - 82, 64,108, 17, 16,180, 26, 13,250,247,239,143, 35,191,254, 84,187, 58,194,209,224, 56, 33, 24,134,129,201,100, 66,133, 80, 0, - 33, 77, 1,119, 53, 96,188, 24,176, 98, 14,188, 72, 0,189, 64, 8, 70,167,135,202, 84,123,172,147,175,143, 14, 12, 67, 96,162, - 89,168,212, 26,228, 92,207, 71,193,221, 82, 24,104, 51, 52, 21, 74, 84,104, 85, 48,178, 52,136,144, 64,167, 87, 67,163,191,137, - 91,133,106,148,105,117,181,210,100,237,164, 52, 70,173, 67,193,185,203,184,119,249, 38, 52,218,235,208,170, 84,224, 33,132, 72, - 64,192, 19, 17, 40,202, 98,245,117,197,185,246, 65,252, 7, 78,185, 3, 28,224, 30,128,123,243,230,205, 51, 0,192,220,185,115, - 79, 37, 37, 37,121, 91,179,110, 4,144,239, 46,225, 53,107,214, 44,141,137,137, 1, 0, 68,132,132,132, 90,125,226,130,134,236, - 28, 54,243,191,213, 18,224,176,248,194,195,195,135,210, 52,141,228,228,100,188,252,242,203, 24, 59,124,248, 95, 3,253,133, 11, - 22, 75, 80, 72, 8,239,108, 92,192,172,249,243, 43,125,254, 0, 48,123,193,130, 42,150, 1, 39,205,254, 85, 96,211,254,109, 76, -223,134,212,212, 84, 36, 36, 36,224,192,129, 27, 63, 2,248,201, 17,157, 0,161,240,223, 70,218, 4,129, 64,128, 43, 55,114,193, -243, 60, 46,229, 92, 3, 77,155, 65,129, 64, 40, 20,130, 16, 2,142,101, 97,208,233,113,237,247,223, 15, 57, 81,134,148, 61,211, -127,237,229, 81,246, 26, 63, 5, 0, 39,206, 92, 64,219,136,150, 46, 77, 83, 62,144,246,239, 74,109,255,128, 69,243,183,185, 66, -248,231,199,188, 21,189,119,155,123,214,128, 6,129,242, 46,196, 45,218,161,120,154, 20,146,103,198,129,205,222, 7, 86, 99,137, - 55, 40,158,246, 52, 90,166,102,129,229,234,110, 42,237,219,182,111,234,229,229,237,245,229, 55,107,140,209, 67,134,136,251,246, -239,247,211,254, 61,191, 61,127,229,122, 14,192,241,144, 74, 36, 24,208,123, 0,118,239,220,141, 17, 35, 70,240,251,246,237,115, -122, 40,168,174,245,239,223,191, 31, 55,110,220,160, 1,136, 79,158, 60, 73, 79,157, 58,117,124,106,106,234,107,142,232,228,229, -229,161,117,235,214, 0, 64,229,229,229,225,252,249,243,104,217,178, 37, 34, 34, 34, 80, 94, 94,142,236,236,108,180,106,213, 10, -161,161,161,104,217,178, 37,242,242,242,234,110, 40, 20, 21, 31, 23, 23,183,100,240,224,193, 62,167, 78,157,242, 99, 24,102,178, - 76, 38, 27,109, 48, 24, 86,192,178,245, 57,172, 2,192, 42, 88,182, 86,167, 81,199,244,118,145, 72, 20,159, 54, 99,198,250,167, - 67, 66, 72,201,156, 57,232,207,113, 88,181,115, 39, 95,168,215,191,133,191,182,101, 95,127,233,210,165,181, 12,195, 8,125,124, -124, 16, 30, 30,238, 99, 54,155, 33, 18,137,240,119, 67, 77, 46,128, 48, 0,173,199, 68,182,120,183,121,176,247, 4,152, 13, 64, -251, 97, 56, 19, 50, 6,207, 36,126, 7, 67,169, 10, 2, 63, 95, 40, 86,198, 99, 80,167,223, 17,116, 33, 99, 48,128, 22,181,253, - 64, 27,191,102,248,227,194, 47,118, 6, 7, 29, 44, 91, 40,155, 1,179, 9, 66, 78, 0,202,202,196,183,109,119,188,139,200,190, -139, 60, 70,244,236, 82, 77, 9, 21, 2, 16, 1, 34, 41, 24,194,194,170, 7,227,149, 9, 51, 0, 64,145,244, 81, 98,173, 29,129, -229,120, 48, 28, 5,138, 97, 64,209, 38,232, 41, 75,219, 49, 8, 4,240,102, 12,208, 24,120, 16, 17, 1,203,178,208,179, 64,177, -174,246,141,159, 24,154,131, 81, 36, 0,167,103,192,112,106,104, 43,204, 16, 16, 17, 76,140, 25, 52, 79,131, 49,211,128,152, 3, - 69, 0, 34,225,160, 54,176, 40, 42,209, 67,103, 98,106, 84,146, 41,194, 86,238,195, 75,200, 95, 46, 93,179,209, 0,181, 82, 9, -138, 8, 32, 20,242, 0, 47,132,128,184,175,234, 92,189,117,149,110,223,178,189,216, 25,179,127,109,178, 25,236,118,196, 74, 74, - 74, 26, 5,224,246,220,185,115,123,250,251,251, 7,168,213,234, 91, 73, 73, 73, 46, 19, 77, 76, 76,124,115,205,154, 53,104,220, -184,177,253, 61,213,170, 85,171, 14, 60,213,161,195,208, 83, 87,174, 28,108,168,142,144,152,152, 24,109,231, 10,168,139,249, 71, -245,233,211, 39,124, 96,143, 30, 32,190,190, 72, 74, 74,194,156, 57,115, 32, 18,137, 96, 46, 47,135,191,191, 63, 62, 76, 76,172, -140, 11, 72,136,139,115, 40, 4, 84,247,241, 59,138, 9,168,203,163, 80, 93,251,119, 96, 29,112,216,100,202,149,202, 14, 62,190, -190, 40, 45, 47,135,226,196, 9, 8, 41, 1, 76,102, 51,244, 6, 3, 56,142,171, 20, 92, 24, 51, 13,218,100,114,198,165,193, 1, -160,172,110, 0,206,174,225, 27,173,247, 49, 63,121,149, 24, 0,218,202,229,197, 55,107,214, 45, 92,178, 82, 53,107, 29, 25,181, -119,219,183,174,152,155,107, 47, 96, 23,204,254, 85,204,178, 91,254,131, 30,175,255, 3,146,136,110,150,177,162,244, 46,114,148, - 22,193, 95,210,255, 5,228,179, 12,188, 86,215,237,106,214,104, 52, 1, 18,153, 20,109, 34, 34,164, 55, 11,110, 55, 41, 43, 41, -195, 43,175, 77, 80,236, 57,152,129,149,203,146,211,183,237,217, 25,211, 54,162, 45,226, 95,158,136,172, 51,199, 48, 98,248,112, -126,223,254,253, 14,191,217, 94,235,223,191,127, 63,134, 13, 27,102, 19, 22,197,119,238,220,193,212,169, 83,197, 0,224, 76,108, - 65, 89, 89, 25, 6, 13, 26, 4,150,101,145,151,151,135, 99,199,142,161, 83,167, 78,240,247,247, 71,243,230,205,209,163, 71, 15, - 80, 20, 5,138,162,208,164, 73, 19, 71,237,180, 83,151, 46, 93,190,232,223,191,191,224,194,133, 11,126, 44,203, 22,109,221,186, - 85, 99, 48, 24,146, 0,216, 59, 77,223,125,254,249,231,243,247,236,217, 19, 65, 8,185,139,218, 55,230,233,153, 48,112,224,250, -190, 66, 33, 41, 89,178, 4,188,217, 12,133, 64,192,101,233,245,147, 96,217,198,221,134,119,230,205,155, 39,164, 40, 10, 74,165, - 18, 55,110,220, 40,238,210,165, 75, 40,254,134, 16, 86, 99,254,109,195,252,101, 3,159,239, 30, 62,213, 79, 38,234,195,176, 92, -185,144,103,253, 16,208, 68,112, 87,101,132,161, 84, 13,136,133, 96, 85, 90, 20,148,211, 64,112, 11, 80, 28, 45,173,203,196,123, - 93,163, 65,187, 0, 63, 48, 38,224,122,230,143,104, 19,245, 92,165, 2,103,166,205, 16,129, 66,133,209,178, 67,237,136,168, 94, -144, 5,135, 99,197,250, 95,107,205,240,136,174, 4,123,206,243, 16, 73, 1,113,139,231, 64,231, 31,173,180, 2,136,196, 18,152, - 97,132,143,204,178, 35,233,206, 61,155,240,199,201,204, 58, 77,146, 28,199, 65, 76, 27, 96,134, 24, 20,197, 0, 70,203,192,102, - 54,155, 97, 50,138, 32, 16,138, 0, 35,192,115, 22, 23, 65, 75,121, 4,144, 85,243,140, 2,189,145,131, 64, 64, 96,102,204, 48, -154, 56,104,180,150,118,104,230,120,208, 38, 14, 16, 2, 2,145, 0, 66, 41, 64, 12, 44, 56,194,128,131, 1, 90, 3, 0, 56, 30, - 88, 88, 0, 20, 7,240, 4,160, 40, 14,132, 8,192,241, 4, 20,101, 85,156, 56, 10, 28, 69,129,112,206, 41,200,118, 65,126,226, -122,182, 35,111, 0, 33,115,231,206, 45, 78, 74, 74,138, 6,240,210,220,185,115,135, 39, 37, 37,233, 0,148,185,101,178,138,141, - 21,175, 89,179,230,219,152,152, 24,200, 27, 53,170,188, 47,111,212, 40,192,106, 5, 8,121, 20, 29,134,166,105,133,205,247,207, -107,181,248,228,147, 79, 96, 42, 43,131, 45,242,173,141, 85, 88, 17,153, 76, 24, 53,106, 84,113, 97,113,241,120,103, 52,237, 6, -116,201, 84,177, 0,212, 97, 33,192,233,211,167, 73, 77,194, 67, 21,161,214, 68, 67, 69, 43, 97, 52, 26, 17,224,239, 15,169, 88, - 2, 51,203,128,231,121,176, 44, 11,154,166, 97, 54,155,193, 49,172,179,241, 12,220,181,188, 60,170,173, 92,110,211, 8,184,107, -121,121,212,143, 91,127,149,218, 91, 4,218,202,229,170,134, 50,223, 23,228,102, 55,152,230,239,110, 12,192,144,140, 18, 20,203, -211, 33,110,209, 14, 36,162, 27, 90,174, 59,139, 82, 35, 7,111, 33, 1,253,223,237,184,122,227, 38, 28,237, 90,108, 96,104,156, -206, 58,137, 47, 86,124,142,167,163, 6, 98,222,255, 91,128,223,246,254,134,159, 54,252,128,254,131, 7,198, 52,151,183,128,208, - 75,132,131, 71, 15, 98,227,247, 63,224,151,237, 91, 33,150, 74,249,157, 59,119,214,185, 62,196,182,109,219,170, 48,126, 27, 84, - 42,149,203,229,163,213,106,225,239,239,127, 2, 64, 95,185, 92,142,222,189,123, 67, 32,176,184, 89, 91,182,108, 9,137, 68, 2, -181, 90, 13,185, 92, 14, 95, 95,223, 91, 90,173,182,101, 29,228, 46, 93,184,112, 97,233, 47,191,252, 50,178,109,219,182, 29,182, -110,221, 90, 81, 94, 94,190, 16,192, 70,123,249,101,200,144, 33,239,175, 91,183,110, 11,128, 98, 0,177, 0,126, 7,208,189, 6, -122,103, 87, 43, 20, 75, 3,178,179, 63,122,149, 97,240, 57,192,125, 91, 81, 49,177, 26,189,151,102,204,152,241,249,148, 41, 83, -112,243,230, 77,236,222,189, 27, 12,195, 28, 2,240,234,147,194,212,123,244,232,129,115,231,206, 85,250,253,235,180,176, 84,187, -110, 53, 38,178,197, 98, 63,153,168, 79,137,198,248,219,241,107, 37, 73, 16, 72,128,171, 71,241,172,156,199, 63,167,143, 66,239, -206,114,204, 72,120, 30, 47,182,166,129,139,251,193,139,100, 12,234, 12,214, 81, 33, 71,149, 15,161, 4, 24,241,226, 63,176,241, -203,101, 22,101, 81,111, 2,107, 0,182, 43,206,225,192, 41,203,140,194,102, 45, 34, 64, 9, 29, 51,175,145,221, 9,204, 70, 96, -231,238,125,136, 28, 62,221,162,253, 67, 4,129, 12,136,123, 33, 22, 35, 7,143,182,116,252, 91,185, 96,140,117,111,213,204,243, - 60, 24, 98, 97,240, 38,218, 18,252,103, 50, 26,160,215,235, 81, 81, 81, 1,173, 70, 13,173, 86, 11,141,202,162,101,189, 0, 0, - 32, 0, 73, 68, 65, 84,182, 2,198,138, 10, 24, 12,134,218, 27,127, 5,129,193,200,194, 96,100,161,211,155,161,173, 48,161, 92, -107,130, 74, 67, 67,173, 53, 67,165,178,156,149,101, 12,148,229, 12,148,106, 6,165, 74, 26,247, 74,107,207, 35,197,243, 96, 1, - 16,150,128, 80, 28,120,194, 3, 60, 15,158, 23,128,229,254,170, 62,206, 58,122,184,106, 27,239,216,191, 35,142,237, 57,134,223, - 14,253, 86, 41, 20, 92,189,117,213,213, 54, 23, 14,160,245,242,229,203,207, 3, 88,253,225,135, 31,190,215,170, 85, 43, 38, 53, - 53,149, 36, 39, 39,187,172,117, 77,137,141, 37,226,176,176,109, 0, 16, 22, 22,118,223,243,105,211,166, 49,217, 87,175,110,106, -168, 88, 0,155,249,223,217,125,227,109,190,127, 0,216,188,121, 51,174, 23, 21, 1, 0,118,101,102, 86,121,118,245,234,213,208, -144,144,144,242, 71, 49, 8, 12, 29,218,202, 54,239,186,202,125,219,181,237,185, 35,120,249,249, 94,225, 88, 22, 26,101, 57, 74, - 75, 75, 81,166, 42,135, 78,175,135, 78,175,135,182,162, 2, 58,181, 6, 90,149, 10, 70,131, 30,180,209, 8,142, 97, 29,142, 57, -109,229,114,219,152,193, 1,160,237,221, 1, 0,240,227,214, 95, 49, 63,121, 85, 0,128, 48,151, 27, 98,235,200,168,234,130, 67, - 68,167, 33, 81,143,122, 80,190,251,138, 28, 45,215,157, 5,137,232, 6,211,225,116,220,122,163, 39,188,133, 4, 71,135,133,128, - 81,151, 32,114, 95, 49,132, 14,154, 95, 70, 70, 6,121,123,230, 59,184,126,245, 42,178, 50,143,194,223,215, 31,227, 94, 25,135, -128,224, 32,156, 57,153, 13, 31,177, 20,222,222,222,104, 34,111,138, 77, 63,111,194,135, 31,127,132, 10, 55,152,184, 13,189,122, -245,114,249, 29, 95, 95, 95,168,213,234,190, 20, 69,209,205,155, 55, 71,159, 62,125,208,185,115,103, 52,106,212, 8, 82,169, 20, -114,185, 28,221,187,119, 71, 64, 64, 0,180, 90,109, 75, 95, 95, 95, 71, 36, 63, 61,124,248,112,198,134, 13, 27, 68,229,229,229, -243,170, 49,235,216, 65,131, 6,125,177,110,221,186,239,194,194,194,150, 16, 66,124, 0,124, 8,160, 46, 51,217,199,139,181,218, - 79,223, 98, 24,246, 91,131, 97,124, 53,122, 49,175, 38,252,235,151,233,239,205, 18, 92,189,122, 21, 39, 78,156,192,186,117,235, - 42, 0,252,243, 73,211,236,171, 7,189,215, 22, 4, 95,125, 16,144, 8, 40,226,155, 95,166,251,105, 83,214,205,127,158,187,165, - 60,105, 96,201,117,148,222,132,244,151,119,177,100,128, 22,217, 11,251, 96,101,116, 5,188,183, 79, 3,148, 5,168,224,165, 23, -173,146, 87, 45,248, 43,170,255,252,133, 95,241,175,127,109, 64, 27,191,174,248,243,248,121,236, 87, 92, 70,116,255,206, 24, 54, -200,210,208,120,129, 16, 52,235,252, 71,142,232,217, 1,139, 63, 93,134,125, 23, 53,240,145,119,194, 11, 47,140,194,111,135,182, - 97,247,111,155, 44, 31,199,154, 33, 17,213, 61,206,241, 28, 11,150,179,104, 51,176,106, 51, 52, 77,195,104, 52,194, 96, 48, 64, -167, 55,192,160,215,193,160,215, 65,111, 50,130, 54,213,190,237,115,153,193, 23,234, 10, 22, 26, 3, 7,141,129,179,252,175,229, - 80,161, 99, 80,161,103, 80,174,100, 81,166, 52,163,172,220,140,178, 50, 51, 74, 75,105,220, 43, 53,215, 41, 0,252,101,254,191, - 95, 85, 19, 10,120, 8, 8, 1, 95, 45,234,159, 39,142, 21,167, 15,226, 63, 64,199,254, 29, 43,175, 15,172, 63, 80,105, 17, 56, -182,231, 24,174,222,186,122,211,149, 6,151,158,158,254, 95,158,231,187,196,196,196,196, 71, 68, 68,132, 0,160, 56,142,147,152, -205,230,192,153, 51,103,250,213, 98, 10,174, 17,226,176,176,249,107,214,172, 25, 25, 19, 19,131,136,144, 16,167, 92, 87,245, 52, -255, 71, 1, 64,100,135, 14, 14, 3,216,218, 54,110, 28,157,156,156,140, 63,111,221,210,252,178,127, 63,174, 92,185, 82,169,245, -183,111,223, 30,214,103,244, 47,251,247,227,214,173, 91,184,154,157,109,112, 68,115,214,252,249,152,189, 96, 65,165,121,223,246, -191,237,218,246,191, 43,177, 0, 73, 73,105,252,144, 33, 67,222,181,103,250,182,115,239,222,189,145,148,148,230,148,118,125,237, - 74,110, 54,195, 48,160,105, 19,148,247,138, 81,114,183, 8,165, 69,247, 80, 90,116, 15,202,226, 18,168,202,202, 96,210,233, 44, -241, 51, 42, 21,156, 8, 2,100,230, 39,175, 18,206, 79, 94, 37, 4,160, 1,192,245,237,213,237,190, 68,118,113, 1, 78,163,105, -235,200,168,194,220,108, 69,247, 62,127,229,161,117,207, 23,163, 84, 37, 55, 20,245,105, 31, 36,174,188,138,230,239, 14,114,148, - 58,228, 79,126, 10,252,205, 11, 8,253,207, 25,120,175, 61,141,187,175,200,209,123, 95, 49,136, 72, 2, 33, 1,132,148, 99, 1, -244,194,197,139,228,147,101,139, 49, 99,246,251, 48,115, 44,174,228, 93,195,132,113,227, 33,150, 74,177, 99,251, 78,192,204,194, -100, 52,225,104,246,113, 24, 12, 21,152, 50,105,210,225,183,223,126,187,174,186, 38, 99,198,140,137, 30, 62,124, 56, 8, 33,200, -200,200,184,207,164,255,193, 7, 31, 56,253,157,193,193,193,184,115,231, 14, 0, 8, 83, 82, 82, 80, 82, 82,130,174, 93,187, 34, - 32, 32, 0, 20, 69,225,228,201,147,160, 40, 10,132, 16,220,185,115, 7,193,193,193,206,144, 93, 66,211,244, 96, 0,155,237,238, -141, 27, 52,104, 80,242,228,201,147, 3, 83, 82, 82,164,132, 16, 10,192, 54, 88,102, 1,220,115, 64,111,206, 9,179, 57,178, 58, -189, 87,231,254,178,229,229,241,211,200,200,119, 82,144,121,226, 18,146,147,147, 57,141, 70,243, 38, 44,179, 11,158, 56,244,232, -209,163,242,112,202, 5, 0, 32,119,211,241,155,137, 74,157,233, 52,128, 28, 0, 77,178,174,149,124, 61,184, 67,216,199,194,155, - 39,130,176,110, 34, 32,241, 6, 76, 58,128,231, 97, 22, 72,239, 29,253,243,238,183,168, 99,245,165,141, 63,125, 21, 61,126, 66, -188, 2, 0,116,156, 25,215, 85,249, 0, 88,180,241,139, 64,116,116, 55,132, 53,106,140, 50,181,198, 98, 43,160, 25,220, 85,233, -234,252,168,102, 45,250,163, 32,223, 58,205,147, 8, 49,162,187, 37, 6, 96,223, 69, 51,126,219,149,142,123,165,119, 16, 28, 96, -153, 73, 16, 32, 22,161, 91,100, 15, 40,182,215, 97,210,133, 16, 98,142, 1, 11, 1, 56, 66, 64,177, 28, 96,102,192,138,132, 0, -161, 96,235,147, 28, 15,203, 90, 1,117, 96,175,226, 38,121,126,160, 47,239, 37,230, 33, 20,217, 89, 24,204, 0,195, 3, 70, 26, - 96, 77, 44, 8, 33, 32, 98, 2,134, 5,116, 38,224,100,150,154,244,232,209,156,175,209,228,111,227,150, 20, 7, 98, 53,255, 91, -132, 2, 2,150,163, 64, 9,172, 51, 5, 0,240, 2, 30,224,157,179, 2,216, 51,255,154,174,143,237, 57, 22,225,108, 67,139,137, -137,233,156,158,158,254, 57,128, 30,233,233,233,251,210,211,211,143,198,196,196, 36,182,110,221,218, 76, 8, 9, 94,185,114,229, -254, 15, 63,252,112,194,178,101,203, 14,215, 33,124,218,180,127,225,236,217,179,231,207,158, 61, 27,251,246,237,131,238,222,253, -125, 57, 34, 36, 4, 55,111,222, 4, 0,133, 51, 11,249,212,182,232, 79, 98, 98, 98,212,154, 53,107, 20,171, 87,175, 70,100,251, -246,209,167, 46, 95,118,104, 42, 62,126,241, 98,230,128,255,207,222,151,199, 53,121,108,239, 63,147,141, 0, 42,130,187,104, 85, -172,168, 85,235,130, 21, 80, 43,137,162,181, 90,187,252,106,212,234,181,245,171, 45, 65,237,117,235,130,182,182,118,209,170,189, - 23,181,171,196, 46, 87,187, 88, 37, 88, 91,183,186,160, 9, 42, 34,136, 86,235, 10, 8, 42,130, 11, 74,194,150, 0,217,230,247, - 71,242,198, 16, 3,121, 19, 80,180,125,159,207, 39, 31,222, 45,135,201,204,188,243,156,115,230,204,153,190,125,159,186,112,236, - 88,103, 0, 62, 0, 62, 55,250,248, 64, 88, 93,141,110,237,218, 97,193,130, 5, 72, 77, 77, 93, 25, 26, 26,154,146,154,154,186, -191,160,160,192,141,114,119,119, 30,128,122,196, 0,212,208, 3, 83, 82, 82, 72, 92,156,236,216,209,163, 69,169,114,185, 92, 4, - 0,113,113,178,193, 43, 87, 42,211,192, 50, 9, 80,231,190,143,189, 83,121,253,198, 40,139,201,220, 67, 87, 90,138,210,219,183, - 64, 8, 15,148, 90, 80, 85, 85, 5, 74, 41, 40,165,184,116,238, 60,140,134,106,252,153,156,236,174, 14, 29,199,156,230, 0,120, - 99,164, 81,150, 49,210, 40, 56, 46, 11,180, 77, 17,176, 70,135,110,131, 36, 5, 57, 25, 42, 0,232,220,169, 19, 78,101, 88,245, -228,220, 63,183, 1, 0, 90, 61, 50, 64,122, 43,255, 68,163, 13,198, 3,255, 40, 66,230,211, 64,191,176,104, 20,205, 30,140,182, - 95, 31, 65,182, 70,135, 64, 17, 65,177, 70, 11, 1, 33,110, 61, 0,246,119, 51, 53,181,198,147, 93,187,118,165, 99,198, 62,141, - 29,219,118, 32, 49, 49, 17, 31,188,251, 30,246,170,247,131, 47,224, 35,184, 67,112, 84,105,105,221, 75,151,183,110,221,170,182, - 41, 2,146, 81,163, 70,213,136, 5,216,183,111, 31, 46, 94,188, 88,165, 80, 40,218, 57,123,147, 92,246,151,206,157,145,151,151, -135,199, 30,123,204, 52,111,222, 60,209,166, 77,155, 16, 16, 16,128, 11, 23, 46,220,229,121,205,203,203, 67,103,246,237,236,152, -120,110,234, 19, 79, 60,241,209, 75, 47,189, 20,144,153,153,217,180,170,170,234,255,124,125,125,159,177, 5, 6,254,206, 82,158, -227, 66,249,169,207,252,123,211,134,161, 35, 94, 32,159, 38, 3,164,253,179,248,100,205, 59, 84,147,115, 97, 58, 0, 37,254,198, -168,161, 0,204, 85,227,236,103,146,234,236,185,106,251,148,102,254,103,146,146, 63,202,171, 76,186,240, 71, 91,142, 9,242,227, - 63,193,175,174,242, 55, 81, 94,121,113,185,225,104,218,197, 27,123, 10, 53,250,148,185,106, 92,175, 77,201,152,242,175,197,234, -131, 71,210,164, 0, 84, 22, 62, 51,205,199,199,197,178,235,120,255,245,233,208,235,171, 81, 86,105,141, 1, 48,240,124,176,121, -107,221,105,118, 11,242,211,200, 11,207,254,219, 74,150,102,198,114, 54, 97,116, 31,130, 73,179, 86,193,207,207, 7,205,124,197, - 82, 0,170,156, 51, 39,164,235,191,216, 90,231,128, 36,160, 38, 24,136, 85, 9, 0, 33, 48, 83,106, 85, 4, 76,182,229,126,132, - 7,129,197, 2,147, 45, 56,208,157, 18, 80, 82,217, 28,149,213,197, 16, 9,120,246, 52,103, 38, 11, 96, 52, 82, 24, 77, 20, 21, -149, 22, 16, 62,129, 25, 4, 70,203, 29,215,189, 43,152, 45, 60,240,136, 25,196, 76, 64,121,212,238,254, 39,181, 24,207,140,164, -179, 23, 54, 17,119,185,161,207,167,157,175,111,223,177,187, 45,250,244,233,115, 61, 36, 36,228,133,203,151, 47,119, 75, 76, 76, -204, 0,240, 92, 82, 82,210,115,142, 15,175, 88,177, 66,189,112,225, 66,233,138, 21, 43,220, 17,132,189, 66, 98, 99, 99,107,125, -232,197, 87, 94,177,250, 0, 61, 75, 12, 68,157,220,254, 0,128, 65, 61,123, 74, 51, 88,144,191,125, 0, 62,117,202, 30,173, 58, -184, 79, 31, 75,124,124,252,151,227,198,141, 51,101,101,101, 9,174, 92,185,130,206, 45, 90,164,237,216,177,131, 85,128,226, 61, -202, 3,224, 72,238, 55, 83, 82, 82, 28, 99, 60, 78, 59,212,179, 91, 37, 64,185, 98,165, 78,182, 48,238,197, 11,251, 15,164, 53, -247,247,111, 86,166, 45,129,201,100, 2,181,189, 7,218,155, 69, 40,211,106, 65, 41, 69,255,232,104,233,159,201,110,243, 32,153, -112, 39,230,132,103, 91, 14,200, 11, 31,240, 56,198, 72,163,236,171, 0,114, 46, 95,102,173, 4, 68,143,125, 73,146,188,243, 23, -187,149,255,187,242, 59, 21, 0,180, 10, 25, 34,189,149,151,170, 6,128,198, 33,127,122,183, 18,128,111,208, 47,246,125,220,176, - 88,208,119,125, 6, 50, 70,183, 65,175, 29, 55, 33, 32, 64, 83,161,119,123,179,237,216,177,131, 76,124,105, 34, 29, 62,114, 4, -182,109,249, 13, 31,175, 92,129,184,210, 82, 80,139, 5,155, 55,111, 65, 97, 97,225, 51, 0,118,184,147,227, 74, 17, 0,128, 23, - 94,120,225, 36,128,114, 54,101, 89,191,126, 61, 25, 53,106, 20, 61,113,226,132,104,192,128, 1, 24, 49, 98, 4, 84, 42, 21, 30, -121,228, 17, 84, 87, 87, 35, 42, 42, 10,148, 82,203,137, 19, 39,120, 66,161,208,155,140,128,143, 5, 4, 4,172,158, 56,113,162, -240,220,185,115,205,170,171,171,107, 11, 12,100,139,254,193,253, 38,108,232, 55,108, 34,249, 46, 5, 40,171, 4, 12,151,118, 91, - 52, 57,170,105,168, 25, 24,248,208,128,201, 3,224,104,249,187,186,230,210,149,234, 64,254,204,249,249,207, 36, 21,249, 87,110, - 87,164, 1,104,103,123,121,171, 1, 20, 2,200,155,171,134, 91, 23,167,226,235,157,234,161, 67,251, 72,205,180,137,202,241,229, -168,208,149, 89,215,253,243,252,144, 91, 14,178,230,235,141,172,126,224,214,109, 95,144, 91,154, 60, 9,120,122,149, 35, 23, 54, -105, 18, 0,179, 81, 11, 80, 29, 70,247, 97, 55,161,107, 4, 31,160,212, 74,212,224, 67, 68,109,138,128,141,252,173, 57, 0, 1, -152,217,205, 77,164, 29,191, 74,194,122,183,163, 38,163, 6, 2,219,194, 94, 74, 41,204, 38,138, 42, 35, 80, 86,110,130, 17, 20, - 38,202,131, 64, 72,112,251,166,177,214,114, 30, 59,182,146, 0,192,224,200,183, 40, 49, 90,173,127, 10,128, 82, 2, 80,155,197, - 64,249, 32,124, 11, 44, 22, 1,178,115,182,176,250,205,175,126,252,170,244,114,238,229,186, 8, 88, 8,235, 82,141,186,216,201, - 94,243, 75,150, 44, 97,252,163,167,108, 86,241, 29,162,126,241, 69,201,150, 45, 91, 84, 54, 37, 64,229, 78, 9, 88,167, 84, 26, -255, 60,125, 90,214,185, 79, 31,243, 19, 61,122,232,108,125,180,218,230, 16,177, 67, 54,122,180,213,226,232,211,199,253,116,199, - 91,111, 73, 1, 96, 96,247,238,119,221,203,204,202, 82,103,156,247, 94, 25,234,211,179,231,215, 60, 30,207,124,225,216, 49,255, - 54,109,218,220, 78, 45, 40,216,224,206,234,191, 15,172,227,216, 15,116,182,128, 63,102,106,160,194,169,173,217, 40, 1,231,100, - 11,227,194,183,125,251,221,150,144, 46,157, 31,171,174,174,130,217,104,130,197, 98, 65,211,192, 64,148,106, 52, 12,249,179, 81, -162, 74, 62,124,227,223,173, 1, 24,114, 46, 95, 22, 49,243,255,233, 39,254,194, 24,105,148,101, 73,252, 23,238,146, 3,217, 49, -107, 78, 28,189,144,117, 65,234, 72,254, 0, 48,252,169,231,164, 7,246,252,174,190,149,151,234,125, 37,214, 18,224,231,250, 58, -123, 14, 27,248, 71, 17,240,199,235,246,243, 71,127,191, 97, 63, 46, 53,154,189, 46,239,230, 95, 54,147, 33, 67,134, 60, 61,106, -236,232, 93,175, 77,157,113,248,241,190,125,134,110,251,125, 59,210, 78, 30,199,241,227,199,119,214,229, 6,174, 67, 17,152,177, -117,235,214,111,183,110,221, 26,177,117,235, 86,214,133, 27, 53,106,212,240,189,123,247, 30,216,177, 99, 7, 66, 66, 66, 48,114, -228, 72, 4, 4, 4,100,151,150,150,134,158, 61,123, 22,121,121,121, 60,161, 80,136, 81,163, 70, 69,239,221,187,215,211,159,122, -174,180,180,116,229,246,237,219,235, 10, 12,244, 4,127, 22,158, 76, 92,254, 91,210,179,239, 84, 6, 79, 65,229,177,197,150,107, -135,150, 77,173,135,188, 7, 78, 17, 96,237, 1,168, 13,115,213,208, 1,248,203,246,241, 10,135, 15,159, 86,199,198, 46,148, 38, - 40, 62, 86, 5,119,234, 6,160, 26, 66, 31, 49, 10,174,151, 97,227,142, 84,226,185,188,157,234,105,175,206,199,250,239,127, 5, - 44, 87, 0, 8, 96,170,170, 68,112,187, 0,233,178,183,102,176,182,230, 96,182, 64,192,179,192, 72, 4, 16, 82,211, 29, 69, 0, - 38,128,154,193, 54, 48,204, 17,199,207, 92, 39, 0,208, 54,136, 71,133, 2,171,181,111,178, 88, 19, 24,149,148, 83,152, 77, 0, - 95, 96,129,217,196,110,228, 56,146,246, 31, 2, 0,225,131, 22, 80, 48, 57,225,121,128,133, 88,221,253, 89, 57,219, 61, 42,228, -183,239,125,171,110,128,254,197,202, 92, 97,200,223,193, 19,224,118, 57,214,177, 11, 23,146,142, 57,185, 12,235,120,214,237, 51, - 13,153, 58,248, 46,229,214,186,196, 47,193,106, 91,123,183,111, 72, 3,231, 1,112,174, 91,157,155,165, 86,172,250,142,114,197, -202, 11,178,133,113,189, 1,240, 47,164,164, 24,171,244,149,176,152,205,232, 25, 22, 38,109, 23,250, 24,142,253,177,157, 93, 29, - 83, 50,113,207, 31, 59,237,167,131, 31, 11,177, 31,239,249, 99,231, 93,231,117,133,198,127,253,185, 85, 65, 30,241,212,243,210, -115, 23,114,113,253,202,105, 21, 0, 28,216,243,187,170,205, 35,189,165, 55,243,207,120,220,238, 19, 38, 76,128,167,233,125,205, -196,167,206,251,249, 47,180,197, 31,215,170,238,249,128,159,154,154,250,135, 66,161,224,101,102,102, 90,246, 31, 77, 65,139,150, - 45,156, 87,122,120,132,173, 91,183,126,167, 80, 40,126,144,203,229, 70, 79,190,247,230,155,111,170, 0,144,105,211,166,209,220, -220, 92,100,100,100,160,188,188, 60,180,105,211,166,104,209,162,133,125, 47, 0, 47,200,159,193,127, 82, 82, 82,132,105,105,105, -125, 12, 6,195, 98,212,156,203,247, 6,239,158,217,252, 47, 97, 64,215, 31, 22,148,230,238,157,210, 0,242, 26, 21,204, 42, 0, - 87,215,189, 82, 0,220, 14,130, 10,133, 96,237,218,181,238, 93, 85,123,142,168, 59,116, 30, 65,110, 22,164,209,214,193, 29,161, - 41, 55, 97,227,182,195, 94,119,208,245,223,174,182,125,183, 13, 5,110, 34,176,169, 0,203, 22,189,230,209, 75,255,205,209,156, -123,182,129,205, 13,141,133, 0,128,216, 87, 72, 13,149, 70, 88, 0,248,249,249, 65,111,210, 19,179,201,115,121,233, 25,214, 61, - 3,194,159,152, 79, 45,148,143,203,151,118, 53,230,238,102,108,151, 14,114,187, 4,178,168, 31, 71,194,111,224,105, 1, 67, 92, -156,204, 7,128,121,229, 74,165,185, 62,130,148, 43, 86, 50, 27,249,216,219, 52,247,140,103,235,244,231, 44,255,194, 43,101,204, -121, 43, 96, 71,236,223,243,155,218,185,175,221,204,247, 46,127,128,187,141,125,156,117, 96, 19,241, 65, 37,175,238, 21,169,185, -229, 38,132, 54, 21,220,151, 87,197,182, 86,191,193,222, 57, 79,201,191,198,248,236,253,134, 63,108,240,137,193, 96,248, 13,112, -191, 41, 29, 75,188, 93,154,187,119, 35,106,198, 6, 60,212, 74, 0,171,193,199,219,125,132, 57,112,112, 68,183,110,221,144,147, -147,195, 85, 4, 7, 14, 28, 56, 60, 36,224,113, 85,192,161, 33,192,145, 63, 7, 14, 28, 56,112, 10, 0, 7, 14, 28, 56,112,224, -192,129, 83, 0, 56,112,224,192,129, 3, 7, 14,156, 2,192,129, 3, 7, 14, 28, 56,112,104,116,212, 8, 77, 61,121,242,164,215, - 81,155,174,130, 9, 57,121,156, 60, 78,222, 3, 35,175,206,232,112,174,254, 56,121,156,188,191,151, 60,143, 21, 0,135,129,194, - 83,184, 27,120, 26, 82, 30,135, 7, 19,148,107,183,135,178, 29, 88, 63,175, 80, 40,252, 1, 60,113,248,240,225,101,124, 62,127, -176,143,143, 15,244,122,253,145,161, 67,135,190, 11, 32, 67, 46,151,235, 31,132, 10,176,101,135, 84,253,147,199, 21, 74, 41, 61, -115,230, 12,250,244,233,195,189,147, 28, 60, 82, 0, 60, 90,135,204, 38, 81,142, 43,121,142,137, 79, 60,149,247, 15, 28,208, 89, -225,169,167,158,146,238,217,179, 71,205, 86,102,112,112,240, 93, 55, 10, 11, 11,157, 7, 83, 40,149, 74,194,178,140,247, 76, 9, -168, 45,159,127, 99,201, 91,181,106,213,136, 45, 91,182, 36,103,103,103, 3, 0, 66, 66, 66,158, 77, 79, 79,223,238,109,251, 58, -246,123, 74,169,253,253, 96,174, 51,239,138,237, 58,113,163, 60,179,109, 7, 79,200,255,177, 51,103,206,108, 41, 43, 43,235,209, -169, 83, 39,220,190,125, 27, 85, 85, 85, 0, 48,120,203,150, 45, 42,127,127,255, 11, 10,133,226,121,185, 92, 94,231, 86,146,103, -206,156,241,200, 32, 72, 77, 77,149,202,229,114,181, 39,223, 81, 42,149, 42,153, 76, 38,245, 38, 1, 20,245, 48, 9,195,132, 9, - 19, 60,121, 63, 0, 0,157, 58, 89,119,192, 45, 47, 47, 71,117,181, 53, 13,186, 78,167,243,228,125,171, 19,167, 79,159,166,131, - 7, 15, 70,207,158, 61,225,227,227, 83, 84, 93, 93,253, 8, 55,140,254,243,224,156, 12,232,158, 37, 2,226,172,216,123,139,223, - 19, 70,187,125,230,249,153,187, 61,146,169, 82,221, 49,144,178,179,179,225,239,239,111, 31,132, 24,176,217,252, 67, 38,147, 81, -165, 82,233,124, 78,106,121,198,171,186,141,138,186,179,157,171, 43,249,245, 1, 33,132, 14, 27, 54, 76,154,146,146,226, 17, 89, -108,217,178, 37,185,117,235,214,120,249,229,151,161,213,106, 45,241,241,241,219, 86,172, 88, 49,105,225,194,133,155, 61,252,255, -248,227,143, 63,236,231,163, 71,143,198,238,221,187,235, 60,103, 35,214,169, 47,211,176,176, 48, 0,160, 14,153,225, 60, 34,255, -210,210,210,180,174, 93,187, 54, 3, 0,177, 88, 12, 95, 95, 95, 20, 21, 21,161,164,164, 4, 1, 1, 1, 40, 42, 42,234,177,123, -247,238, 12,133, 66,209, 93, 46,151,223,168, 75, 94,239,222,189, 33,147,201, 16, 18,114, 39,235,223,202,149, 43,107, 60, 19, 23, - 23, 7, 0, 56,122,244,168,202,155,126, 83,159,236,143,107,214,172,169,237,150,125,175, 2,111,225,239,239,143,115,231,206, 65, - 40, 20,194, 96, 48, 96,247,238,221,200,201,201,193,162, 69,245,219,113, 54, 48, 48,144, 15, 32,250,224,193,131,187,163,162,162, -110, 62,255,252,243,109,146,147,147,193,231,243, 91, 53,111,222,156, 15, 14,255,104,242,103,174, 57, 43, 1,127,155, 32,192,240, -240,112,201,253,182,184, 27, 19,193, 3,151,218, 63,222, 66,171,213,218, 45,126,157, 78,135,117,235,214,217, 63, 30, 12,180, 46, -207,199,143, 31, 79,101, 50, 25, 5, 64,157,159,241, 20, 7, 15, 30, 84,189,245,214, 91,232,210,165, 75,131,213, 95,231,206,157, -201,219,111,191, 13, 74, 41, 82, 82, 82, 84,158,182,123,118,118, 54, 70,143, 30,109, 1, 0,145, 72,196, 11, 13, 13, 69,124,124, -252,166, 86,173, 90,209,240,240,240, 49, 30, 88,156,247,170,139,144,176,176, 48,202,252,174,227,199,143, 51,251, 1, 48,237,194, -218,237,175,213,106,183,136, 68,162,102, 0, 48,123,246,108, 76,153, 50, 5, 34,145, 8,190,190,190, 16,139,197, 32,132,128,207, -231,163,180,180,180, 25,128,120,133, 66, 81,167,236,184,184, 56,132,132,132, 32, 47, 47,207,254,137,139,139,171,241,169, 15,100, - 50,153,212,246, 59,189, 30, 19,230,207,159,111,255, 56,142,151, 78,215, 45,108,229,117,234,212, 9,254,254,254, 88,188,120, 49, -252,253,253,177,109,219, 54, 84, 86, 86, 54, 8,249,219,222,101,170,213,106,255,111,234,212,169,232,214,173, 91,155,221,187,119, -227,230,205,155,184,122,245, 42, 74, 74, 74, 12,247,115,108, 82, 40, 20,146,130,130, 2,170, 80, 40, 36,174,238,229,228,228,208, -139, 23, 47,114, 9,232,238, 3,249,199,196,173, 64, 76,220,138, 90, 21,131,251,162, 0, 16, 23,168,235,186, 55, 72, 79, 79, 87, - 53,132, 18, 48,101,202,148,135, 70, 9,168, 47,244,122,253, 93, 86,191, 55,205,203,144,201,248,241,227,237, 86,126, 82, 82, 18, -234, 75,252,142,214,191, 82,169, 36,195,134, 13,147, 42,149,202, 26, 30,129,250, 32, 49, 49,145, 0, 32, 81, 81, 81, 82,103, 79, - 3,203, 65,215,100,243, 6,160,117,235,214, 88,186,116,105,213, 27,111,188, 97,200,203,203,219,185, 98,197,138,145,141,221,190, - 14,123, 0, 16,199,118,242,176, 93,158,200,201,201,233, 1, 0, 51,102,204, 64,105,105, 41,174, 93,187, 6,161, 80, 8,129, 64, - 0,129, 64, 0,161, 80, 8, 95, 95, 95, 84, 86, 86, 34, 57, 57,121, 50,128, 64,119, 66,243,242,242,160, 84, 42,237, 31, 71, 79, -192,202,149, 43,145,156,156,236,245,239, 86, 42,149,106,219, 20,128,170,129,222,229,218, 18,119,179, 30, 63, 47, 95,190,140,157, - 59,119, 98,233,210,165,232,212,169, 19, 90,182,108,137,148,148, 20, 44, 90,180, 8,254,254,254, 0, 0, 62,191, 94,134,122,187, -233,211,167, 79,252,207,127,254,131,244,244,116, 92,187,118, 13, 38,147,233,229, 22, 45, 90, 4, 2, 48,222,239,190, 23, 28, 28, -140,152,152, 24, 85,110,110, 46,117, 36,255,152,152, 24,213,163,143, 62, 10,179,217, 12, 14,247, 22,142,196,239,120,220, 24, 30, - 0,234,226, 83,215,245, 70, 83, 2,198,140, 25,211, 16, 74, 0,245,224,195, 26, 47,190,190,167,193, 26, 36, 59, 59, 27, 58,157, -174, 86, 55,255,145, 35, 71, 26, 66, 49,168, 55, 14, 30, 60,168,178, 41, 22, 72, 73, 73, 81, 19, 66,208,186,117,107, 85, 67,118, - 78,198,253,111,243, 4,212,137, 85,171, 86,141, 25, 50,100, 8, 5,128,248,248,120,209,247,223,127,143,151, 95,126,153,113,205, -139,255,250,235, 47,145,237,222,222,240,240,240,231,216,252,255,209,163, 71,227,233,167,159,182,187,247,153, 99,230,156, 57,102, -233,254, 7, 0,216,172,127, 87,237, 64,156,238,215,137,221,187,119, 47,107,217,178, 37, 0,224,226,197,139,200,207,207,199,137, - 19, 39, 96, 48, 24, 64, 8,129, 64, 32, 0, 33, 4,102,179, 25,122,189, 30, 91,183,110, 5,128,190,158,120,142,100, 50,153, 75, -229, 37, 47, 47,175, 94, 74,128,195,111,175,151, 55, 0, 13, 48, 85,106, 52, 26, 49, 96,192, 0,168,213,106, 92,190,124, 25, 3, - 7, 14,180,223, 83,171,213, 8, 10, 10,178, 43, 2, 94,160,253,244,233,211, 11,190,251,238, 59, 68, 71, 91, 55, 50,106,223,190, - 61,204,102,243,143, 0, 74,238, 55,241,200,229,114, 53,163,124,134,132,132,224,216,177, 99,148, 33,127, 70,249,235,222,189, 59, -155,241, 97, 16,128, 31, 96,221,243,172, 46,140, 5, 16, 3,160, 21, 71,251,247,185, 99,179, 98,195,251, 24, 4,104, 83, 2,164, -233,233,233,106,111,101,116,238,220, 25, 83,166, 76,193,207, 63,255,236,109, 76, 0, 1, 64,127,254,249,103,151, 55,119,237,218, - 5,219, 61,143,101, 31,189,244, 24, 34,186,156, 67, 97,230,226,122,213,147,227,156,127,114,114, 50,162,163,163, 17, 19, 19, 99, - 39,255,142, 29, 59, 54,132,210, 87, 47, 69, 32, 42, 42, 74,114,240,224, 65,220,190,125, 91,202, 92,147, 72, 36, 82,165, 82,169, -138,138,138,146,120, 58,111,239,230,127, 73,217, 40, 0, 91,182,108,217,201,204,253,235,116, 58,172, 92,185, 18, 21, 21, 21, 16, - 10,133,240,241,241,193,165, 75,151,176,116,233, 82,104,181, 90,196,199,199,255,182, 98,197,138,225, 11, 23, 46, 84,185, 33,217, - 26,202,128,187,152, 0, 22,117, 14, 55, 59, 0,218,167, 3,220,253,222,160,160,160,193,213,213,213, 48,153, 76, 56,114,228, 8, -248,124, 62, 12, 6, 3, 42, 43, 43, 97,177, 88,236,239,177,209,104, 68,117,117, 53,243, 78,247,118, 39,183, 54, 55,127, 92, 92, -156, 61, 30, 32, 36, 36, 4, 69, 69, 69,245, 86, 68, 29, 86, 5,176,237,139, 26, 0, 65,174,110,172, 94,189,218,171, 66,196,199, -199,227,173,183,222, 66,255,254,253,237, 30, 16, 38,125,118,255,254,253,145,149,149,133,214,173, 91,123, 35,186,211,244,233,211, - 47,127,247,221,119,142,227,103,240,181,107,215,174, 53, 38,177, 12, 28, 56,144, 48,164, 63,112,224, 64, 12, 28, 56, 80, 5, 0, - 89, 89, 89,232,209,163, 7,219,118, 56, 9,192, 23,192, 38, 0,147,224,180, 37,184, 13,175, 3,248,194,118,252, 46,128, 30,128, -251, 45,234,255,206, 96,118, 3, 92,183,114,161,221,242, 95,183,114,161,253,222,125, 87, 0,238, 55, 30, 20, 37, 96,202,148, 41, -244,221,119,223,189,203, 21,232, 13,249, 55,164,245, 15,192,165,245,207, 88,253, 66,161, 16, 55,110,220,104, 84,242,119,180,254, - 29, 3,186, 84, 42,149,163, 23,224,190, 7,108,102,103,103,227,229,151, 95,214, 3,240,243,247,247,199,123,239,189, 7,161, 80, -104,191, 63,109,218, 52, 0, 64, 96, 96, 32,198,141, 27,135,195,135, 15, 31,184,143,229, 36,142, 30,128,186,148,128,176,176, 48, -231,173, 98, 93, 42, 3, 6,131, 1, 26,141, 6, 85, 85, 85, 8, 8, 8,128,143,143, 15, 76, 38, 19, 40,165, 48,155,205, 48, 24, - 12, 48, 26,141, 48,155,205,142, 10,253,237,186, 10,153,151,151, 87, 35, 0,144,153, 14,112,244, 8, 56,222,175, 47,188, 8, 8, - 20,215,118,195, 49, 38,192, 19,101, 96,233,210,165, 24, 59,118, 44, 58,119,238, 12, 63, 63, 63, 72, 36, 18,104, 52, 26,248,251, -251, 67,171,213, 98,253,250,245,224,241, 60,118,200,118,152, 62,125,250,229,121,243,230, 97,219,182,109,120,238,185,231, 0,160, - 45,128,155, 15,194, 56, 44,151,203,213, 1, 1, 1,210,137, 19, 39,170, 0, 96,243,230,205,210, 73,147, 38,121,210, 22, 6, 0, - 83, 0,252, 92,135, 18,224, 56,213,246, 8,128, 62, 0, 50, 56,219, 30, 53,136,191, 54,252, 45, 51, 1,214,151,252, 25,120,107, -165, 59, 14,200,203,150, 45,171, 55,249, 51, 24,208,191, 31,246, 31, 80, 97,227, 1, 63,187, 82,112,244,210, 99,245,250,141, 97, - 97, 97,200,203,203, 67, 82, 82, 18, 58,118,236,136, 13, 27, 54,120,108,117, 41, 20, 9, 18, 7, 15, 78,131,144, 63, 51, 31, 95, - 84, 84, 36,117,190, 55,108,216, 48,105, 82, 82, 82,131,197, 2, 0, 86,247, 63, 91,239,147, 86,171, 61, 15,235,188,176,101,243, -230,205, 88,191,126, 61, 0, 96,211,166, 77,208,106,181,204, 99,166,172,172, 44,180,106,213, 56, 94, 73,167,104,255,187,148, 51, -182,251,196,231,229,229, 29, 49,155,205,208,106,181,184,125,251, 54,180, 90, 45,244,122, 61,244,122, 61, 42, 42, 42, 80, 86, 86, -134,210,210, 82, 84, 86, 86,162,186,186,154,153,219, 77,171, 75,166, 51,185,187, 10, 36,117, 94, 21,192, 22, 54, 87, 63,117,113, -205, 19,248, 53,116,123,108,216,176, 1, 18,137, 4,126,126,126, 56,119,238, 28,212,106, 53,252,253,253,241,254,251,239,227,240, -225,195, 88,180,104,145,167, 10, 64,219,233,211,167, 95,157, 52,105, 18,126,253,245, 87,134,252,219, 63, 40,228,111, 29, 23, 20, - 18,134,252, 1, 96,226,196,137,170, 11, 23, 46,120, 58,181,202, 40, 1,176, 41, 1,206,211, 1, 23, 29,142,243, 1,156,230,104, -255, 14,156,131, 0, 27, 69, 1,184, 31, 65,128, 13, 77,254, 54,226,110, 8,203,141, 44, 91,182,172, 94,228,255,226,235,123, 48, -160,255, 29,215,205,150, 95,183,218, 61, 2,251, 15,168,188, 82, 2,228,114, 57,108, 75,195,160,215,235,177,111,223, 62, 44, 93, -106, 93, 81,112,250,244,105,152, 76, 38, 15,100,197,170, 1,107,224, 31,165,148, 9, 6,172, 23,249, 51,214,127, 93,110,254,134, -138, 5, 96, 20, 9,137, 68, 34,117,247,108, 72, 72,200,168,248,248,248,176,244,244,116,193, 15, 63,252,192,187,112,225, 2,166, - 77,155,102, 98,234, 49, 62, 62, 30,233,233,233,248,225,135, 31, 4, 87,174, 92, 65,120,120,184, 91,153,247, 34, 6,128,177,164, -157,148, 0,202, 40,125,108, 17, 26, 26,154,105, 50,153, 96, 48, 24,112,235,214, 45,220,184,113, 3, 55,111,222,196,205,155, 55, -113,235,214, 45,104, 52, 26,232,245,122, 84, 87, 87,163,180,180,148,249,159, 5,117,201,100, 2,253, 28,149,208, 58,202,238, 17, -249, 51, 57, 0,156,175,213,167,127,184, 88, 13, 96, 87,242,216,202,200,201,201, 65, 86, 86, 22,244,122, 61, 34, 35, 35,209,183, -111, 95,108,216,176, 1,239,188,243, 14, 68, 34, 17,248,124, 62, 4, 2,214, 14,217, 14,211,167, 79,191, 62,105,210, 36,100,100, -100,224,131, 15, 62, 96,172,223,235,120, 64,150, 49,103,102,102, 82,102,206,255,196,137, 19, 88,183,110,157, 20, 0,186,119,239, - 14,199,192,192,122, 42, 1,115, 97,157,255, 31, 15, 96, 22,128,112,252,195,221,255,192,157, 72,127, 87, 65,128,206,171, 0,238, -215, 20, 0,245,240,250,223,133,252,237, 74, 64, 61,166, 18,106,144,191,171,243,253, 7, 60, 31,223, 28, 7, 93, 63, 63, 63,244, -236,217,179,198,253,244,244,116,143,228,141, 31, 63, 30, 73, 73, 73, 96, 20, 1, 0,212,118,205,227,117,231, 27, 54,108, 80, 1, -192,238,221,187,165,174, 34,214, 83, 82, 82,212,151, 47, 95,118,105, 61,186, 66,109, 73,127, 24, 69, 35, 37, 37, 5, 81, 81, 81, - 82,149, 74,229,182,239,164,167,167,239, 91,190,124,249,136,212,212,212,253,161,161,161,200,206,206,134, 86,171, 21, 4, 6, 6, - 98,250,244,233,208,104, 52, 87, 82, 83, 83, 59,133,134,134, 34, 53, 53,149,196,198,198,186, 83,142,239,154,243,175, 71, 12, 64, -141,119,139,201,151, 96,203,157, 96,247,204, 56,204,255,187,109,143,136,136,136,119,212,106,245, 28,179,217,140,178,178, 50, 24, -141, 70,251,188,127, 85, 85, 21, 40,165,160,148, 34, 43, 43, 11, 6,131, 1,209,209,209, 47,201,229,114,147,171,164, 35,181, 33, - 58, 58, 26,209,209,209, 53,130,254, 60,157, 2,112, 36,122,155,203,159, 58,246, 15,219,170,128,134, 30,215, 88,143,159,204, 82, -191, 55,222,120, 3,106,181, 26, 82,169, 20, 57, 57, 57,104,210,164, 9,242,243,243,193,231,243,217,122, 0,200,244,233,211,175, - 78,157, 58, 21,135, 14, 29,194,251,239,191, 15, 0,193, 0,174,225, 78,254,135, 70,183,252,153,241, 37, 47, 47, 15, 97, 97, 97, - 76, 63,147,198,196,196,168, 66, 66, 66,144,149,149, 69, 89, 6, 2, 58, 42, 1,147,108, 10,192, 38, 0, 71, 0,200, 1, 72, 0, -220, 0,135,134,235,192, 13,157,141,207, 85,192,207,202,149, 43,107,189,222,152,228,111, 91, 1,112, 47,180,104,175,101, 94, 45, -112,223,191,125,125, 61,243, 90,186, 11, 18,243, 20,209,209,209,210,164,164, 36,245,132, 9, 19,104, 98, 98, 98, 13, 69,192, 73, -225, 99, 93, 15,177,177,177,110, 53, 27, 15, 19, 3, 81, 39, 69,194, 58, 42, 73,165,172,200,223, 97, 48,183,207,235,135,135,135, -255, 43, 62, 62,254,199,113,227,198, 33, 43, 43, 11, 87,174, 92,233,180,120,241, 98,105,108,108, 44, 43,121,247, 40, 15, 64,141, -122,174,133,248, 88,101, 12,148,203,229,186,132,132,132, 37,187,118,237,250,208,100, 50,161,164,164,196, 30, 3, 0, 0,183,110, -221, 66, 73, 73, 9, 40,165,140,213,238, 17,203, 50,243,255, 97, 97, 97,246, 8,118,230, 58, 91, 37,192,133,149,127,215, 52,212, - 61, 32,127,143,193, 40, 1, 11, 23, 46, 68, 74, 74, 10,198,141, 27,135,229,203,151,227,205, 55,223,132, 64, 32,128, 88, 44,118, - 59,134, 80, 74, 45, 51,102,204,192,143, 63,254,136,239,191,255, 30, 0, 58,218,200,191,193, 13,170,250,160,176,176, 16, 59,119, -238,172,145,197,209,118, 44, 29, 62,124,184,202,203, 37,143,102,155, 18,176,195,102,253, 71,112,228, 95, 59, 92, 5, 1,178, 82, - 0, 60, 73,196,225, 45, 97, 55, 52, 26,130,252,235, 75,212,247, 2,115,231,206,149, 94,184,112,161, 65,101,218, 92,164, 13,186, -148,142, 33, 60,219,218,122,198, 43, 64, 9, 33,176, 88, 44,216,178,101, 11,107, 37,224,173,183,222, 98,202,121, 87, 12, 0,143, -199,131,197, 98,193,219,111,191,173, 98, 75,158,117,201, 75, 73, 73, 81, 59,102, 69,244,162,223,253,180,124,249,242, 91,169,169, -169,187,217, 90,253,247,193,219, 70,156,189, 61,181, 40,124,172,148,128,216,216,216,143, 20, 10, 69,210,207, 63,255,124, 86, 36, - 18,129, 89, 21, 96,177, 88,208,188,121,115,104,181, 90,200,100, 50, 68, 71, 71,251,201,229,114,183, 11,188,153,241,197, 49,248, -239,248,241,227,136,142,142,174, 49,158,184, 27,135,226,226,226,104, 94, 94,158,212,217,197,239,109, 26, 96, 71,184, 8,240, 51, - 1, 48,173, 94,189, 90,108,179, 70,121, 14, 31,143,148, 0,199,196, 63,179,102,205,178, 31,151,149,149,185, 29,155, 8, 33,100, -250,244,233,244,135, 31,126,120, 30,192,239, 15, 34,241,216,136,158,120,122,143,141,210,238,132,235, 15,195, 24,126,191,193,172, - 2,112, 69,252,172, 86, 1, 52, 52,169,215, 38,239, 65, 81, 30, 30,228,142,243,217,103,159,169, 27, 90,166,211, 26,233,123, 6, - 39,247, 63,219,151,154,109, 46,116,226,193,239,189,167,191,117,209,162, 69,123,234, 83,159,163, 71,143,174,177, 44,246,233,167, -159,174,225, 25,240,112,238,159,120,232,237, 97, 85,110,185, 92,126, 78,161, 80, 52,217,187,119,239, 39,249,249,249,115, 42, 43, - 43, 97, 54,155,209,175, 95, 63, 12, 28, 56, 48, 62, 58, 58, 58,142, 13,249, 3,192,209,163, 71,237,199, 81, 81, 81, 53,174, 59, -159,187, 25, 87,136,163, 66,203, 40, 19,182, 56, 0,175,218,125,194,132, 9,181,221, 18, 56,140,151,162,123, 53,174,184,241, 84, - 88, 0,224,251,239,191,231, 54, 76,225,192, 90, 9,168,141,252,107, 83, 0, 26,186,115,113,157,149, 3,241, 80,179,255,199,213, -141, 35,225,223,131,105,129, 6,121, 7,229,114,185, 14, 86,215,235, 92,230,218,249,243,231,217, 16,151, 29,189,123,247,110,240, -241,192,149, 66,235,173,203,255, 94, 43,139, 28, 56,254,184,159, 74,128,219,202,245,118, 31, 97, 14, 28, 56,112,224,192,129,195, -195, 11, 30, 87, 5, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56, 60,132, - 48,193,131,237,138, 57,255,124,202,173, 0, 0, 32, 0, 73, 68, 65, 84,252, 51, 33,224,170,128, 3, 7, 14, 28,184,177,157,195, - 63,188,147,156, 60,121,210,235,136, 75, 87,193,132,110,228,213,185,254,216, 11,121, 13, 93, 62, 78, 30, 39,239, 31, 45,239,207, -119,174,120, 61,176,244,255,164, 19,238,181,188,227,139,188,151, 23,182,252,110,121, 76,253, 41, 20, 10,137,209,104,196,165, 75, -151, 84, 6,131, 1, 2,129, 0, 5, 5, 5,120, 41,160, 51,246,100,102,162,242,241,142,136,136,136,144,242,249,124,102, 93,123, -163,181,175, 66,161,120, 12, 64,235,179,103,207,238,108,223,190, 61, 79,163,209,136,219,183,111,191,212,215,215,119,173, 92, 46, -191, 6, 0, 9, 9, 9,188,132,132, 4,115,109,242, 18, 18, 18,154,218,188, 5,250,216,216, 88, 10, 0,139,255,253,228, 55,242, - 39,243,167,111,204, 12,189, 36,104, 61, 42,162, 73,211,102, 21, 0, 40,165, 84, 0, 32, 48, 33, 33,225, 42,247,190, 61,216,242, -238,181,150,200,118,211, 23, 79, 83,224,122,156, 50,119,101,228, 83, 18, 65, 80,128, 42, 55,251,162,244, 81,159, 38, 88,112,230, -160,250, 65,210,178,234,200, 71,206, 45,113,105,100,140, 29, 59, 86,178,107,215, 46, 85,252, 59,214,243,223, 14, 61,137,131, 7, - 15,178,106,151,127, 77,123, 69,194, 35, 68,149,117,225, 2,180, 90, 45, 58,117,234,132, 38, 77,155, 98,107,210, 22,214,237, 58, -126,252,248, 26, 47,110, 82, 82, 82,157,123, 41,216,178, 43,122,213,111,152,141,154, 40,165,245,235,119, 50, 77,205, 87, 85, 25, -228,189,172,176,213, 64,200, 43,214,227,188,245,192,241, 5,245,111,212,241,183,107,150, 47,169, 37,171,175, 41, 20, 10,170,211, -233,164, 91,183,110, 85,229,229,229, 65, 38,108,129,182, 29, 91,161, 74, 87, 9, 95,189, 9, 67,222,124, 13,195,198, 77,196,142, -239, 18,176,125,255,126,213,168, 81,163,164, 15, 64, 23,206, 54,155,205,237,242,242,242, 44,125,251,246, 21,133,134,134,226,196, -137, 19,239, 84, 85, 85,141, 85, 40, 20,209,114,185, 92, 19, 27, 27,107,169,107, 73, 88,108,108,108,185,227,249, 87, 95,125,197, -219,253, 83, 92,183, 14, 51,250,227,237, 65,189, 90, 29,221,251,223,196, 45,167, 37, 39,187,245, 30,190,156, 16,162,145,203,229, - 5,253,250,245,179,216,148, 6,206,211,240, 15,115, 19,121,170,105,176,202, 54,230, 13,249,127, 29,245,172, 36,178, 85, 7, 21, - 1, 69, 78, 69, 9,218,181,239,172, 50, 90,204, 88,212,103, 48,138, 58,181,146,126,183,227,119, 86,138, 64,204, 36,208, 30, 93, -153, 51, 62,182,238,181,224,208, 49,138,152, 73, 64,143,174,192,130,101,245, 35,110,102,131,146,250,102, 39,115,165, 76, 52,148, -220,250,128, 82, 74,177,132,128,124, 84,231, 51,192, 18,130, 9,231,101, 15,204, 90,235, 59,228, 79,109,228, 63, 12,135, 15, 31, -102,245,221,180,163, 47, 82,147,177, 7,148,202,235, 72, 79,179, 38,172,201,190,144, 5, 0,216,185,147,208,172,139,227,165, 11, -230,178,107,151,145, 35, 71, 90,246,237,219,199, 75, 74, 74,194,129, 3, 7,106, 36,195,113,134,151, 41, 84,237,205,228,162, 35, - 83,234,133, 66,193,164, 11,175,119,206,130,144, 87,236, 27,237,172, 94,189,186, 97, 20, 0,135,122,178,237, 78,200, 10,185,185, -185, 80, 39, 38,170, 62,138,158,128,126, 83,102, 65,212, 38, 16, 16,216,146,253, 89, 40, 96, 17,194, 82, 77, 49,230,149, 24,228, -127,190, 2, 71,142, 28, 81, 41, 20,138, 26,233,110, 27, 1,102, 30,143,215,186,101,203,150, 80,171,213,130,190,125,251, 98,208, -160, 65,188, 27, 55,110,244, 63,117,234,212, 25,133, 66, 49, 64, 46,151,223,176,145, 53,143,101,221, 53, 25, 49,124,100,200,242, - 85,219,120,113,211, 78, 55,139, 24, 61, 83, 26, 17,158,252,228,155, 95, 20, 60, 19,250,196,203, 97, 0,202, 97,141, 49,224,213, -198, 15,142,137,173,220,245,163,122, 43,164, 28,156, 61, 9,238,188, 5,246, 99, 79,130, 0, 41,211,184,253, 94,238, 3,133, 66, -193,243,128, 8,157, 55,169,160, 97, 97, 97, 8, 11, 11,243, 58, 79,188, 98,114,140,100,114,255, 72, 85,247,118,193,232,218, 46, - 24,143,183,106,143, 96,223, 38, 16, 91,128, 46, 62, 77, 16,144,115, 77, 53,253,153,231, 36,108,100,245,232, 10, 92,200,229,225, -252, 69, 63,156,201,109,134,231, 71,250, 99,213,187,124,244,232, 74, 26,204, 72,175, 47, 73, 51,219,156,134,132,132,168, 50, 51, - 51,145,153,153,137, 15,127, 58,133, 71,199,196,169, 0, 80, 15,183, 60,165,108, 63, 50,153,204,253, 91,188,196, 90, 71, 97, 97, - 97,144,201,100, 46, 63,204, 51,158, 98, 92,223, 15, 36,142,229, 25,219,103,137,164, 33,218, 99,236,216,177,146,157, 59,119,170, - 8, 33,120,227, 19,130,223, 14, 13,195,161, 67,135, 88,125, 55, 49,113,138, 36, 34, 60, 22, 67,135, 94,199,231,159,127, 94,227, -222,228,201,192,152, 49,192,252, 57, 73,170, 85,159,177,107, 19,134,252,213,106, 53,120, 60, 30, 38, 78,156, 8, 62,159, 95, 31, -178,191,203,242,119, 53, 32, 19,226, 29,249, 55, 24,194, 86, 1, 0,214,172, 89,131, 53,107,214, 88,175, 13,136,111,180,226, 28, - 56,112, 0, 95,189, 16,131,129,207,201, 32,104, 17, 4, 34,228,131, 39,228,131, 47, 22,129,231, 43, 6, 64, 65,205, 38, 80,131, - 1,175,189, 50, 11,101,251, 51,145,155,155,171, 82, 40, 20, 18, 52, 30, 72,102,102,102,100,199,142, 29, 69, 22,139, 5, 41, 41, - 41,216,182,109, 27, 2, 2, 2, 16, 25, 25,217,110,243,230,205, 31,219,158, 99, 21, 16,168, 80, 40,248,135,247,255,242,191, 71, -252, 10,218,232,202,249,152,188,164, 2, 95,254,247, 51,160,105,111,193,127,227, 90,119,201, 61,241,243,100, 7,238,224,213,162, - 24, 18, 7, 82, 39,214,203,196,126,236,120,253, 30,237,133,193,161,129, 61, 0,246, 86,218,184,251,231,146,174,143,118,109, 46, -255,232, 53,139,135,236, 72,194,194,194, 40,147,150,212, 33, 61, 41,245, 52,109,167,226,133, 87, 36, 79,117,124, 84, 37,170, 50, -193,247,191,111,193,164, 55, 64,252,198, 50, 4,136,196,168, 18, 86, 66, 87, 85, 9, 95, 16, 84, 95, 45, 82,125,250,233,167,210, -183,223,126,187, 78,242,189,144, 11,172,219,100, 1,160,183,125,128, 39,159,224,225,133, 81,164,198,123, 19, 51, 9, 88,183,201, - 43,242,150, 42,149, 74,234,173,181,206, 88,253,153,153,153,119,234,224,176, 17,149, 6, 29, 0, 96, 68,220, 62, 40, 87,142,244, -200,203,144,187, 34, 23, 66,146,115,167, 35,144, 66,144,150, 61, 28,206,139,208,234,255, 94, 96,215,176, 31,217,243,205,147,218, -210,206, 18,155,210,119,252, 56,187,118,150, 63,251,165,100,221,182,127,171,182,159,250, 0,203,231,253,134,112, 73, 40, 54,126, -125, 8,223,238,181,110, 16, 52,243, 95, 31, 72,215,254,244,129, 87, 74, 85,252, 59,160,192, 78, 40,127, 56, 11, 74, 41,154,182, -126, 28,135, 14, 29,130,109,223,130, 58,203,183,234, 51,153, 68, 38,107,161, 2,190, 2,240, 27,210,211,129,240,240, 59,247, 63, -254,248,206,241,252, 57, 73, 42, 95,191,197,210,153,175, 45,173,179,156, 12,249, 71, 69, 69,193, 98,177,224,203, 47,191,108, 80, - 7, 13, 0, 88, 44,150,187,201,159,214,253,254,242, 38,104,107,188,252,204, 16,110,145,185,120,206,238,231,179, 30,244,237,123, -247, 28, 59,111,162,182,134,154,111,177, 76,195,188,121,243,236,247,231,205,155,135, 53,107,214,128,215,109,198,157,255,106,123, -222,149, 60,193, 68,215,229,115,222,201, 90, 48,145, 93,249,170,170,170,208,182, 83,103,192, 98, 0,207, 7, 32, 2, 62, 76,229, -165,168,202,187,132, 91, 5,133,232, 48, 88, 2, 34,106, 14, 98, 52, 0,124, 30, 86,206,124, 19, 35,215,125,128, 5, 11, 22, 52, -244,184,204,138, 21, 21, 10, 5,161,148, 54,175,172,172, 28, 28, 20, 20,132,172,172, 44, 88, 44, 22, 92,186,116, 9,235,215,175, - 71,207,158, 61, 17, 28, 28,252, 50,128,215,156,200,186, 86,111, 0,165,180,101, 39, 94,186,164,221, 35,163, 69, 37, 41,167, 81, -170,245,193,143, 59, 76,216,117,244, 39,204,145,249, 10, 4,122, 75,152, 45,166,192,165, 2,192, 17,122,227,163,182,233, 30, 87, -158, 1, 30,139,142,200,204, 27, 66,178,104, 24,214,165, 40,154,231, 94,204,197,201, 31, 78, 67,161, 80,120,100, 61, 48,228,160, -215,255, 12,189,126, 35, 52,154,104,198, 58,246,232, 7, 14,242,105,166,106, 93,101,134,120,201, 44,152,111,107, 96,186,120, 25, - 2,145, 16,126,132, 15,127,194,135, 63, 95,128, 32,161, 24,180, 92,135,235, 7,142,184,221,233,197, 21,169, 31, 58,102,177,191, -135,171,222, 37,136, 95, 76,108, 30, 1,239,172,127, 27, 57,171,224, 69, 10, 92,103,242,135,128,143,188,235, 21,184, 94,108, 64, -250, 57,235, 6, 34,221,166,109,135, 39,251,158, 11, 73, 14, 4,164, 16, 62,188, 83,214,191,173, 9, 2, 39, 95, 67,192,164, 51, -240,121,126, 9, 16,236,239,153, 39,151,197,206,109,158,108,241,170,216,246,186, 42, 34,232, 93, 28, 63,120, 9,255,111,252, 56, - 4,183,236,142, 89,255,126, 21, 95, 44,222,139,136,192,197, 88,251,211,135, 94,239,224, 67, 8, 16,187,224,140,221, 98, 25, 58, -116,168,141,144, 44,110, 27,120,202, 36,161, 10, 56, 0,224, 55,148,220,108,130,110,143, 52,193, 55,223, 88, 45,255, 37, 75,128, -144, 16,171,136,146,155, 77, 80,114,179, 9,250,245, 57,175,114, 71,254, 7, 14, 28,128,197, 98,177,147,244,230,205,155, 97, 54, -155, 61,114, 95,215,225,225,185,139,252,173,239,179,123,229,157, 2,100,173, 66, 33,101, 44, 53, 11,165,176, 88,238,238,190,204, -117, 11,165, 88,155,144, 32, 77,176,126,199,229,255,164, 0,161, 20, 36, 33, 65, 33,165,148,226,179,207, 62,179,223,103,142, 19, - 18, 18,164,148, 90,159,163, 0,169, 77, 94,130, 66, 1,219, 61, 98, 54,155, 97, 50,155, 97, 50,221, 93,103,204,117,147,217,140, -175,215,174,149,174, 77, 72,168,165,124, 20,130,166, 77, 1, 33, 31,102,125, 5,206,110, 73,194,251,175,202,209,225,117, 57,250, -175,248, 8,151,254, 60, 1,190,175, 24,198,226,155, 56,125, 84,141,237,135,246,160,244,198, 13,156, 57,115,166,193, 54,214,138, -140,140,100,229, 77, 80, 40, 20, 1,148,210, 65,153,153,153,191,191,247,222,123,189,206,158, 61, 43, 50, 24, 12,224,243,249,104, -218,180, 41, 76, 38, 19, 50, 50, 50, 64, 8, 17,185, 27,235, 19, 18, 18,252, 21, 10,133,111, 66, 66, 66,112, 73, 65,234,159, 31, -254, 47, 63,232,175, 67, 59,160,209,241, 32, 18,240,208, 33, 80,140,210,219, 34,200, 63, 53,225,244,237,254,254,238,120,195, 22, -107, 66, 29,251,162, 77, 49,184,235, 58, 71,215,247, 7, 12,249, 59, 43, 7, 60,119, 90, 40,179,223,119, 13, 55,231,232, 41,158, -123,251,108,238,126,189,126, 35, 0,130,170,170,239, 33, 62,118, 25,250, 61,143,214,184,239, 14,111, 15,136,146, 4,104,202, 97, - 17, 9, 96, 56,126, 22,213,231,243, 80,181,247, 16, 80, 89, 13, 17,165,240, 3, 31, 2, 16, 84, 91, 76,208, 84, 87,225,235,125, - 59,220,202, 92,245,174,213,186,119,132,245,156, 49, 87, 40,178, 46, 82, 44, 88,230,125,127,117,202, 87,206,218,101, 47,147,201, -236,123,107, 51,120,105, 77, 1,246, 31,215, 34,255,102, 21, 0, 32,255,102, 21,114, 10, 42,129,232, 68,102, 99, 20,247,174, 31, - 82,104, 85, 4,202, 79,195,223,255, 34,124,196,229,176, 88, 52, 48, 26,143,131,207, 15,129, 65, 87,220,104,157,117,194,232,127, - 75, 0,130, 47,127,155,129, 38,188, 71, 0, 0,215,179, 40, 6,140,227,227,223, 75, 71, 98,232,200, 94, 0,168,237, 57,207, 16, - 21, 21, 69,223,248,132,160, 73,171, 62,160, 0, 70,191, 48,147,245,188,255,218,111, 22,211,214,173,255, 2,112, 6, 37, 55,155, -160,188,216,186, 5,115,223,190, 64,183,110,192,203, 47,223, 33,255,242, 98, 95,148, 23,251, 34,200,239,122,157, 50,199,143, 31, - 15,169, 84,138,225,195,135,215,112,253, 59,126,188,153, 18,112,245,222,122,131, 88,135,249,109, 66,136,253, 83,219,181, 88,185, - 92, 45,143,113, 63, 39, 30, 19, 19,163,114,101, 57,207,155, 55, 15, 49, 49, 49, 53, 8,181, 54,121,191, 41, 20, 56,115,230,140, -221, 5,239, 88,103, 12,156,175,205,140,141, 85,199,202, 93,111,213, 44,162, 20, 60, 63, 31, 24,111, 92,129, 98,241, 98,172,215, -149, 64, 27, 21, 97,191,255,221, 79,235,241,193,155,175, 34,116,193, 75,248,232,244, 1, 36,106, 47, 97,228,179,207, 34, 36, 36, -196,227, 96, 64, 27,209,211,240,240,240, 26,125,248,232,209,163,170,186,182, 99, 87, 40, 20, 66,133, 66, 49,240,244,233,211,249, - 41, 41, 41,234, 55,222,120, 35,226,203, 47,191, 20, 87, 84, 84,216,183,105,174,170,170, 66,147, 38, 77,114, 38, 76,152,208,125, -200,144, 33,143,184, 81, 36,120,132,144, 78,167,211,182, 20,101,239, 89,112,121,193,162,248,118,219,151,180,199,249, 66, 1, 74, - 43,248,176, 16,160,184,194, 0,218,162,107,213,252,119,150,245,122,230,249,127,189, 6, 55,241, 4, 54,247,127, 13, 87,191,155, - 99, 14,141, 64,254,181, 77, 1, 80,182,174, 28,185, 92,238,238, 33,234,108,253, 91, 93,109,223,215,230, 29,112,251, 79,123,181, -108,163,210, 80, 35, 68,197, 26,136,127, 59, 0, 34,224, 1, 85, 6,208,114, 29,136,201, 4, 33, 0, 51,181,160,202,108, 66,185, -201, 0, 88,220, 91, 81, 76,144,223,170,119,107,213,105, 97, 13, 18,108, 16,133,149, 56, 4,242,185,125, 1,238,178,254, 1,252, -242,122,187, 26,231, 3, 23,230, 65, 72,111,195, 72, 90, 66,169, 84, 30, 96,251, 98,137, 43, 84, 8,250,232, 39,220,122, 35, 22, -183, 53,190,104,111, 60, 11,179, 57, 15, 0,112,229,100,219, 70,235,176,137,187,191, 80,189, 58, 74, 81,131,252, 25, 68, 4, 46, -198,224, 94,227, 17, 25,116, 22,137,187,151,170, 60, 25, 68,134, 13, 27, 70, 83, 82, 82, 80, 92, 60, 2, 45, 90,236, 71,147,150, -189, 65, 41, 5,143,199, 99, 21,136,148,159, 15,228,229,157,177,157, 85, 0,226, 10,104,116,192,160, 65,214, 43, 57, 57,192, 87, - 95, 1,229,101,128,174, 2,168,208, 1,254,129,101,172,202, 86,155,181,159,155,155, 11, 0,248,228,147, 79, 0, 0,161,161,161, -247,194,205,204,170, 14,231,206,157, 91,195, 98,119, 38,110,214,222, 29, 27, 97,219,231,253, 29,240,217,103,159, 97,205,154, 53, - 80, 40, 20, 18,119,193,117, 51,130, 67,145,125,246, 28, 10, 3, 3, 85, 60, 30, 15,115,230,204,185, 43, 38,195,147,242, 61, 89, -221, 28,212, 82,129, 87, 63,121, 23,125,198,143,135,226,147, 79,192,227,221,225, 57, 69,206,153, 59, 30,194, 67,135,176,111,223, - 62, 92,186,116, 73, 42,151,203,213,108, 54, 94,113, 36,255,180,180, 52, 21, 0,100,100,100,168, 34, 35, 35,165,105,105,105,234, -240,240,112, 73,122,122, 58, 34, 35, 35,165,149,149,149,170, 90,198, 92,227,180,105,211,250, 76,153, 50,165, 89,151, 46, 93,176, -107,215, 46,125,105,105,169,160,178,178,210,234,237,176,205,127,108,221,186, 53,116,244,232,209,190,114,185,188,210,133, 24,158, - 3, 89,243,242,178, 78,174,249,224,237,233, 77, 90,116, 83,226, 79,229, 43,248,235, 42, 65,254, 77, 1, 64,121,168, 54, 24,161, -161, 45, 10,103,207,152, 21, 65, 8, 41,100,198,124, 79,126,175, 11, 15, 1, 55, 85,240,128,160, 86, 45, 46, 37, 37,229,174, 79, - 73,161, 22, 37,133, 90,143,218,154,249,220,177, 98,173, 13, 47, 62,118, 25, 62,103, 10, 33, 40,208, 50, 30,128, 26,207,215, 38, -240, 92, 65, 62,142,221,190,134,179,151,242,112,243,210,101,148, 93, 46, 64,249,213, 66,152,244,149, 48, 26, 77, 40, 55, 27,160, - 55,155, 80, 77,205, 48,131,130, 18,246, 74,166, 99,180,255,133, 92,235,249,130,101,140,229,207, 67,252,187, 13,179,226,197,211, - 56,128, 56,165, 22,113, 74,109, 13,194,103, 62,145,113, 25, 16,210,219, 16, 80, 45,126,153, 97, 54,177,158, 2,184,121, 12,102, - 93, 19, 0,192,127, 5, 1,168,190,121, 5,153,159,182, 67,246,207, 99,113,236,211,126,200,201,186,214,168, 29,179,239,160, 16, -232,180,128, 78, 11,232,125,207, 1, 0,126,253,208,136,183,231, 45, 1, 0, 12,137,238,229,177,229,255,194,176,131,208,104,162, - 17,120,116, 63, 86,191,107, 85,114,135, 13, 27,198,202,245, 15, 0,203, 63, 94, 74,186,118, 5, 28, 63, 23, 46, 88,221,255, 0, -208,173, 27,197,154, 53, 64,167,238, 21,120, 44,226, 22, 6,141,184,133,231, 95, 50,178, 46,163,163,197,207,156,135,134,134, 34, - 52, 52, 20,115,230,204,105,232, 42,118,251,174, 57, 98,221,186,117, 82, 87,132,109,247,162,173, 90,133,117,235,214,177,178,132, - 95,123,237, 53, 21, 19,249,239, 10,243,231,207,191,203, 11,224, 10, 7,207,229, 99,250,140,217, 56,190,113, 35, 22, 45, 90, 84, -171,114,194,148,111,255,254,253,168, 43, 96,111,216, 99,143,224,251,239,190, 66,216,228,201, 88,190,124, 57,234, 42,227,188,121, -243, 48, 98,196, 8,120,179, 2, 32, 45, 45, 77,229, 16, 44,135,163, 71,143,170, 0, 32, 61, 61, 93, 69, 8, 65, 90, 90, 90,157, - 50,245,122,125,243, 29, 59,118,224,220,185,115,200,201,201,241,211,233,116, 48, 26,173,253,204, 96, 48, 96,247,238,221,196,166, - 44, 84,178, 40,142,165,186,186, 90,116,124,203,100, 84,101,127,129, 61, 41,185,184,116,157,143, 50, 29, 15,102, 10, 20,234,124, - 49,123,193,187,145,177,177,177, 5, 44, 12, 62,187, 94,193, 44, 57,101, 57, 29,192,161, 17,172,255,218, 20, 0, 2,128, 72, 36, - 18, 72, 36, 18,156, 58,117,202,254,201, 59,118, 5,165,149,165,104, 49,200,243,117,191,199,143, 31, 39, 0,224,231, 55, 5,226, - 99,151, 33,188, 82, 12, 74, 8, 68, 51,138,107,220,119, 75, 92, 34, 62,204, 20, 40,208,149, 32,191, 84,131, 91,101, 90,148, 86, - 85, 65,107,168,196,173,234, 74, 92,175,210,163,176,170, 2, 26, 99, 53,180, 22, 35, 12, 22,247,193,175, 79, 62,225, 98,192,115, -136, 11,120,117, 98, 19, 80,136, 64, 61,222, 6,252, 78,244,190,139,107,172,145,127,179, 10,251,143,107, 49,112, 97, 94,205,186, -160,183,225, 99,185, 2, 31,203, 21,124,240,148, 0,249,249,249, 6,182, 50,183, 92,178,160, 85,124,130,253,252,146,206,140,130, -220, 66,100,165,158,197,141,203, 37,141,222,113, 55,126,157, 2, 0, 40, 43,162,240,171,124, 12,146, 25, 2,252,191, 37, 66,251, - 39, 62,113, 50, 8,123,227,159, 62, 55, 52, 5,175, 44,176,146, 63, 33, 4,191,167, 90,155,128,237,154,127, 6,161, 61,186,215, - 44,231, 70,224,203, 47,129,139, 23,173,158,128, 15, 63,164,118,247, 59,165, 20,129,129,129,238, 71, 96, 91, 31,101,230,253, 63, -249,228, 19,228,230,230, 34, 59, 59, 27,217,217,217, 72, 78, 78,198,155,111,190,137,252,252,252, 70,107, 15,134,232, 92, 89,210, -115,231,206, 5, 33,132, 53, 25, 18, 66, 80,151, 50, 81,215, 61, 71, 28,242, 41, 1,225, 53,193,183,239, 44, 67,147, 29,201,136, -137,137,193,100, 70, 27, 3, 32,239,214, 27,115,195, 6,195,207,207, 15,195,134, 13,195,123,239,189,135,228,228,100,213,242,229, -203, 93,190,127,223, 21,102,227,122,175,199, 16, 28, 28, 44,181, 88, 44,117, 42, 20,117,221, 99, 65,142,118,143, 83,100,100,164, -212,129, 40, 17, 17, 17, 33,117,227, 61, 25, 62,108,216,176,102,249,249,249, 56,116,232, 16, 30,125,244, 81, 8, 4, 2,251, 20, - 71,112,112, 48,219,233, 8,139,237,255,146,174, 61,250,199,173,219,219, 28,127,237, 90,130, 39, 35,123,194, 95,204,131,191,159, - 25,190, 62,213,120,250,185, 9, 22, 0, 26,199, 47, 38, 36, 36,184,155,139,178,175, 2, 96, 57, 29,192,225, 65,243, 0, 0, 32, - 10,133,162,233,220,185,115, 49,119,238, 92, 0, 48,124, 28,251, 49,140, 69, 38,248,250,138,225, 77,227,201,100,214,240, 97,191, -167, 46,130,242,121,120,239, 87,189,163,245,207, 10,126,193,193, 82, 83, 19, 63,104,169, 25,231,116, 90,156, 41, 45,198,217,178, -219, 56, 91,166,193, 57,157, 6, 23,245, 90, 20, 87, 87,161,194,100,194, 53,189,206,254, 63,235,194, 11,163, 8, 86,189,203,199, -170,119,249,160,224,131, 18, 30, 98, 38, 17,188, 54, 73,132, 25, 19, 91,161,107,215, 54,176, 64,232,241, 79,102, 92,253,142,243, -242,117, 36, 5,170, 77,134, 52,167,192,170,200,103,174,176, 6,209,237,121, 43, 0, 0, 32,160, 90,240,169, 14,213, 60,107, 68, -179, 70,163,241,147,201,100,209,158,148, 49, 44, 44, 12,201,201,201,216, 88,161, 67,165,129,135, 87, 54,125,139, 34,177, 47, 42, - 13,141,183, 77,196,184,190, 31, 72,211, 52,203,176,241,199, 68,251,181, 95, 63, 52, 34, 34,112,177,253, 60,230,153,175,164, 20, -172,214, 15,211,213,139,129,105, 11, 70,160,249,209,100, 72, 63,141, 2,111, 44,160, 86,171,189,234,195,157, 58,213,140, 30, 31, - 62, 28,104,222, 28, 8, 9, 1,194,251, 54,133, 88,196, 7,159,119, 71,172,216,215,215,237,128,204,227,241,236,150,127,110,110, -174,221,234,103, 62, 31,125,244, 17, 62,250,232, 35, 92,187,198,222, 43,227,106,190,190,230,125,207,173,175,117,235,214, 73, 87, -175, 94,237,146,176,217, 90,255, 14,174,231,187,226, 20,152,115,139,133, 93, 10,123, 3, 33,176,232,171, 33,108,219, 9,242,165, - 75, 49,205,191, 57,154,171,211,236,247,103,252,107, 26, 62,248,239,183,200, 89,245, 11,222,239, 51, 28, 19, 2,187, 96,223,182, -109,200,203,203,115,249,254, 61, 31, 43, 71,175,222,189,165, 22, 91,153, 24,133,204,113,122,198,213,181,218, 48,115,230, 76, 74, - 8,161, 76, 96, 31, 51,223,239, 72,242,105,105,105,234,136,136, 8, 41,165, 20,204, 84,128,155,122, 75, 17, 10,133,143, 62,255, -252,243,185,165,165,165,208,106,181,240,245,245, 69,171, 86,173,208,188,121,115, 52,111,222,220, 93,229, 89,156, 20, 59,179,143, -143,143,254,197,216,207,165,235,143, 13,196,229,171,101,104, 19,192, 71,100,119,130,199,187, 80,248, 55,107, 86, 2,192, 92, 7, -111,112,251, 13, 60,164,214, 63,224,102, 25,160, 92, 46,175, 80, 40, 20, 62, 0,252,229,114,185, 93, 11,236, 16,213,222, 43,205, -151, 89,234, 39,147,201,168,104,134, 61,242,159, 56,204,255,187, 29,144,223,217,153,168,254, 36,250, 57,232, 77,213, 40,211,233, -145,107, 52, 66,104,177,126,185,212, 88, 5, 11,165,160, 0,118,221,188, 4,157,201, 8, 0, 44, 6, 38,130, 5,203,106,246,113, -107, 60,128, 5,102, 84,227,252,197,114,124,191,185,204,163, 31,235, 72,244, 54,151, 63,181, 29,219,137,157,205,234, 7,235,119, -149, 16,142,248, 26, 64, 8,138,139,239, 4,231,137, 44,215, 97,224,181,195,236, 62,217,184,126,221,110, 57,237,103, 83,190,216, - 95,215,213, 80,188,148, 74, 37,152,210,108, 58,125, 4,209,209,209,141,214,113,183,159,178, 46,239, 75, 77, 62, 11, 0, 24,220, -203,154, 25,239,237,121, 75,112,228,108, 47,252, 55,113, 50, 20, 59,102,177,158,255,127,101, 65, 52,130,130,146,109,103,106,155, -178, 20, 13, 74,173,214, 24, 64, 17, 20,148,204, 74,214,190, 61,123,237, 57, 45, 38, 79, 6,164, 82,130,219, 87, 3,160,211,138, - 81, 89, 38,194,166, 13, 4,115,231, 82, 92, 41, 42, 71,120,100, 4, 82, 14,168, 88, 89,197,102,179,217, 62,223,159,156,108, 45, -171, 35,225, 23, 21, 21,161,168,168,136, 53,255, 59, 16, 6,229,241,120,119,145, 42,165, 32,158, 38, 1,146,203,229,234,215, 94, -123,173, 70, 44, 0,227, 17,240,196, 21, 78, 28,180, 18,139,211,178, 2, 66,216,207,217, 17, 66, 96, 42, 47,135,176,101, 16,248, -126, 77,208,235,197,241,248,104,212, 72,188,195, 44,219,235, 63, 0,230,202, 42, 8, 91,180, 65,159, 8, 9, 58,119,232,130,207, -207,167,161,119,239,222,210, 99,199,142,221,165, 4,196,202,229, 0,136, 10, 0,102,197,198,218,151, 14,154,156,200, 94, 32,224, - 3,244,206, 66,197,218, 10,188,118,237, 90, 2,128,218, 92,252, 36, 35, 35,195,165,139, 63, 45, 45, 77,205,134,252, 19, 18, 18, - 8, 33,100,113,243,230,205,123, 69, 68, 68,116,189,112,225, 2, 78,156, 56, 1,179,217, 12,127,127,127,232,245,250,162,160,160, -160,203,158, 24,125, 10,133,130,215,166, 77,155,125,207, 61,247, 92,155,163,135, 51,176, 70,185, 15,205,136, 8,221,219, 84,227, -226,109,127, 12,237,110,188, 4,192,121, 30,203, 92, 87,155, 56,102,156, 34,132, 56,158, 58,231,125,225,208,200, 16,176,120,233, - 13, 0, 12, 14,131, 10, 45, 72,241,120,126,184, 6,185,215, 66,124,172, 51, 6,150,105,180, 82,163,159, 88, 85,202,179,224, 70, - 85, 5, 96, 52,194,108, 91,215,116,190,162, 4,133,250, 50, 80, 74, 97,203, 47,160,102, 83,188,152, 73, 4,235, 54,221,233,147, - 23,114,129, 30, 93, 77,224, 67, 87, 47,242,119,234,236,238,234,160, 86, 47,128, 82, 57, 75, 5,100, 66,163,209, 24,242,243,243, - 5, 43, 71,130, 23,183,111, 24,230,245, 62, 98,183,194,216, 42, 21,174,188, 46,206,231, 12, 9,177,181,230,176,132, 96,160,109, - 37,135,171,229,126,137,137,137,214, 76,128, 50, 25,101,147,243, 33,118,220,215, 82,197,246,217,170,180, 68,138,200,160,179, 24, - 18,221, 11,135,247,157,197, 81,237, 82, 16, 16,200,199,125, 37, 77,216, 62,155, 85,249,130,130,146, 65, 8,193, 11, 47,188,128, -111,190, 41, 3, 67, 49,214,191,148, 81, 8,104, 77,203,254,118,173,242,162,134, 75,165, 41, 7, 84,170,225,195, 1,195,141,142, -184, 90,226, 3,139,109,182,181,157,174, 13,222,138, 41,199,190,163,221,209,180, 67,119, 41,147, 37,176, 46, 48,196, 95, 80, 80, - 0, 0,184,113,227,134,221, 51,112,243,230, 77,251,192,234, 37,136,131,219,217,249,165, 36,108,242, 1, 56,226,155,111,190,145, -174, 89,179, 70,197, 40, 0,171, 87,175,246,216,250,119, 38, 12,111, 33, 22,139,113,227,202,101,116,233,218, 13, 22, 83, 53,136, -201, 12, 65,211,102,104, 58, 96, 32,154,244,127, 2, 22,157, 9,102,125, 53,168,201, 12,152, 45,136, 91,251, 95, 76,156, 60, 17, - 98,177,216,165, 60,211,166, 64, 86,255,215,213,115, 97,203, 93, 63, 27, 25, 25, 41,181, 41, 0,148, 82,138, 33, 67,134, 72, 83, - 83, 83,239,122,206, 29,249,219,234,202, 2, 96,119,247,238,221,251,127,241,197, 23,134, 91,183,110, 85,141, 28, 57,242,185,204, -204,204,247,245,122,125,113,203,150, 45,229,159,127,254,185,134,109,253, 41, 20, 10, 33,128, 71, 34,194,195, 91,197,206,136,197, -165,130, 75,154,169, 51, 98,159, 76,223,183, 33,254,122,185,102,240,192,168,145,150, 54, 29, 66,255,159,179,149, 95, 87,106, 97, - 91, 31, 35, 14,250, 39,113,193, 1,206,199, 28, 30, 84, 5,160, 46,235,194, 27,242,103,200,166,150,132, 49,172,148,128, 21, 39, - 14,170, 1,144, 73, 3, 34, 41,124,197,208, 82, 19, 12, 38, 19, 44,212,130, 22, 1, 1, 40,208,149,194,147,228, 66,174,150,247, -221,137, 1,240,108, 45,182, 43, 23,127,125,211,245,218,242, 8,140, 27, 56,112,224,246,184,184, 56, 81, 80, 80,144,229,250,245, -235,152,215,251,186, 51,249,179,254, 31,181, 37,236,241, 10,182, 44,127, 46,146, 60,221,245, 12, 91, 36,108,159,165, 6, 64,198, -246, 89, 34,217,121,250, 67, 85, 90, 34, 64, 64, 48,174,239, 7,210,237,167, 62, 80,179, 37,127,166, 47, 21, 23,143,160, 64, 25, - 99,253,194, 21,239,172,143,223,207,244, 7, 82,215,230, 26, 54,171,158, 20,107,123, 75,204,229,229, 42,194, 7,244, 85,190, 32, -229, 38, 8,120, 2,232,121, 98,233,168, 9,175, 98,118, 76,172,219,246, 72, 74, 74, 34, 73, 73, 73,244, 30,190,127,160,148, 18, - 66, 8,117,140,104,119,244, 4,120, 34, 75, 46,151,171, 99, 98, 98, 48,111,222, 60,187, 66,209, 88,169,112,135, 15, 31,142,217, -137,235,240, 81,121, 9,250, 69, 13, 5,175, 77,160,181, 76, 70,106, 77,221, 11, 33, 8, 95, 0, 34,226,227,155,132, 85,104, 54, - 98, 32,186,118,237,234,113,212,126,125,224, 96,221,171,194,195,195,165,169,169,169,245,170,171,220,220,220,232,253,251,247, 95, -225,243,249,219,158,124,242,201,143,103,205,154,117,107,237,218,181, 41,128,117,202,193, 3, 81, 60, 0,201, 39, 78,156, 24,244, -195,250, 13, 60, 17,223,231,234,248,151,198,247,157, 61,123,182,246,235,175,191, 30, 11, 32,192, 70,252,229,204, 6, 65,108, 60, - 10, 28, 30, 12,176,113,255,123,171, 0,212, 91, 97,112, 67, 62,172, 7,164, 77, 39,210,136,108,188, 76, 98,201,202, 81,233,170, - 13, 48,153,205,232, 58,104, 0, 66, 77,225,158, 18,110,131, 5,163, 48, 73,127, 0,168, 24,107,220, 22, 7, 80,175, 28,248, 74, -165,114,135, 66,161, 16, 36, 39, 39, 47, 88,185,114,229,167, 14,202,197,112,199,255,197,214,163, 0,160,193,146,151, 76, 56,207, -196, 89,212,254,251, 38,156,151,121,165,233,239, 60,253,161,154,105, 31, 10,138,237,167, 62,240,170,140, 86,114, 39,120,101,193, -240, 59,102, 47,185,115,111,193, 50,207,243,145,199,189,117, 70, 29, 7,144,181,223, 44,150, 84,234,173,251, 0,220,201,255, 31, -235,241, 59, 98,179,200,204,114,185,188,193,231, 85, 25, 37,160, 33,100,217, 98, 1, 84,204,113, 3,148,205,171,239,117,237,218, - 21,109,231,204,145,174,217,187, 87,149,247,241,111,144, 9, 91,160,185,109,243,158, 74,189, 9,115,223, 92, 4,190, 95, 16,118, -109, 80,224, 84, 75,130, 81,131, 7,123,157,183,223,108, 54,121, 61, 76,176,117,241,179, 80,190,200,243,207, 63,127,139, 82, 26, -223,163, 71,143,255, 21, 23, 23,235,188, 32,126,199,122, 31,150,145,145, 1,139,137, 96,240,144,190, 31,204,158, 61, 91, 11, 0, -179,102,205,178, 0,208,214,167, 73, 29, 60, 78, 53,142, 93,120, 69, 57, 60,100, 30,128,123,162, 20,120, 77,140, 73, 53, 18,236, - 32, 35, 55,171,209, 43,213, 41,233, 15,115,173,222,114,229,114,185, 25,192,127,108, 31,175,229,186, 42, 95, 61,127, 47,105,136, -103,238, 37,172, 4, 79,177, 96, 89,114,131,203,118,151,234,215,131,246, 53,222,203, 58,104,168, 77, 87,228,114,185, 90, 46,151, - 55,136, 44, 82,143, 57, 0,166, 12, 10,133, 2,182,237,123,145,239,176,125,111,234,254,125,246,237,123, 71, 68,140,128, 77,233, -173,245,255,241, 39,106,137,121,115,224,221,196,196,114, 55, 65,119, 74, 64, 67,212,215, 19, 79, 60, 81,109, 50,153, 82, 0,232, -222,123,239,189,122,145,104,108,108, 44,121,239,189,247,168,193, 96, 0,128,189,181, 61,183, 98,197, 10,178,112,225, 66,251,255, -178,165, 2,174,115,108,119, 14,238,228,112,127,193,214,195, 69,188,221, 71,152, 3, 7, 14, 28, 56, 52, 10, 76, 0,170, 0,136, - 27,216,136,115,183, 99, 32,235, 29, 5, 57, 60, 28,224, 26,147, 3, 7, 14, 28, 30, 46, 8, 0, 52, 97, 65,254,122, 88, 3,184, - 27,138, 15, 44,224,150,253,253,237, 58, 18, 7, 14, 28, 56,112,248,251,193,143,227, 11, 14,156, 7,128, 3, 7, 14, 28, 56,112, -224,192, 41, 0, 28, 56,112,224,192,129,195, 63, 29, 53, 92, 58, 39, 79,158,244, 58, 34,215, 85, 48,225,131, 46, 47,100,128, 15, -124,125,110, 64, 40, 42,129,197, 98, 93, 22,198,231,243,192, 35,124,235, 95, 30, 1, 33, 60, 80, 34, 0, 33, 4, 60,152,176,125, -167, 16,148, 82, 4,241, 90,192,147,242,217, 50, 42,182,132, 53,128,167, 28,214, 4, 3, 70,102,201,215,195, 88,127,156, 60, 78, - 30, 39,143,147,199,201,123, 48,229,113, 30, 0, 55, 56,120,248, 34,180,165, 90, 24,141, 20,183,110, 19,236, 73,246,197,222,125, -254,224, 17, 33,246,169,218, 98,239,129,118,216,171,106,135, 67,199, 90, 65, 0, 1,120, 16, 99,104, 36, 15, 62, 34, 31,214,255, - 99,210, 43, 83,233,164, 87,166,210,195,169,170, 42, 35,143,164,158, 61,147,121, 80,117,228,176, 46, 57, 57,185, 10, 64, 83, 78, - 7,125,248, 49,242,169,161,146, 89,179,166, 82, 79, 55,121,122, 88,161, 80, 40, 36,212,134,186,118,215, 99, 11,234, 4,174, 71, -113,224,208, 8, 30, 0, 6,131,135, 12, 98,253, 18, 30, 73,205,112,171,181, 52,180,188,134, 68, 70,166, 16,163, 71,154,113,234, - 47, 95,136,132, 2, 8,248, 2, 8,133, 20, 62,124, 35, 32,104, 10, 1, 42, 49,168,151, 9, 98,145, 15, 40,128,118,109,128,103, -199, 88,176,127, 27, 59,242,191,120, 62, 27,143, 62,214, 21,237,131,155,163,224,202,133, 78, 1,109,187,160,101,123, 51,254,248, -253,119, 36, 39, 39,151,160,145,119,196,146,201,100, 99,148, 74,229, 78,135,243,103, 28,207, 57,212,142,217,179,100,212, 84,117, - 86, 58, 40, 44, 80,101,177, 20,163,180,125,165,170, 67,219, 17,168,168,110,135,111,214,253,244,183,221,233, 44, 38, 38, 70, 53, -111,222, 60, 16, 66,176,122,245,106, 85, 67,228, 4, 96,210, 1,112,252,127,255,225,145,210, 69, 41, 8,143, 87, 87,123, 83,199, -246,100,218,244, 78,242,173,154,237,236,184, 51, 34,135,134, 5,147, 13,208,193, 75,192, 78, 1,104, 44,240,238, 51, 23,142, 25, -101, 4, 5, 31, 2,190, 16,131,195, 9, 90,183,226, 65, 32,224,193, 71,200, 71,143, 80, 30,174, 92, 53, 97, 80, 24, 15, 45,130, -196,248,227, 64, 51, 0, 0,159, 86,130, 82, 11,220,165, 8,158,244,202, 84,250, 87,102, 38, 58,183,239,128,191,210,142, 34,221, - 96,132,246,182, 22, 34,159,166,232,217,127, 8,250, 14, 25, 5,213,118, 37,100, 44,115,227,223, 3,226, 31,174, 84, 42,247,135, -132,132, 32, 51, 51,147,233, 48, 37, 0,230, 40,149,202, 29, 50,153, 44, 90,169, 84,238,255,187,189, 20, 51, 99,101,212, 71,160, -129,128,103, 64, 85,149, 25,165, 58, 95,252,248,243,126,143,234,127,196,200, 33,146,102,190, 26, 12, 31, 34, 66,231, 78,207,170, -154, 53, 11,128,209,100,194,173, 91,183,209, 38,255, 42,114,114,243,240,202,203, 99,232,134, 31,118,121,213,174, 97,182, 61, 21, - 0,246,219,100,223, 79,235, 31,184,179, 29,238,234,213,171,161, 80, 40, 36,141,149, 14,248, 62,190, 47,116,203,150, 45,119,239, -167,208, 72,228,165, 80, 36, 72, 8, 8, 98, 26,160,222,105,254,175, 32,233,175, 58,114,188, 45, 75,166,125,223, 43, 59, 94, 77, -208,185, 85,228,254,248,227, 15,251,249,232,209,163,177,123,247,238, 58,207, 57,220,123,242,119,188,230,168, 8,212,169, 0,164, - 30, 78,199,144,161,225,247,173,208, 22,207,178, 67, 58, 62,236,213, 75,200, 19,240,161,213, 8,208,182,181, 16,109, 91,139, 80, - 81, 33,132, 88, 40,128, 89,224,131, 1,125, 8,250, 61,206, 7,143, 8, 65, 8,129,143, 80, 4, 33,175, 26, 68, 44,130, 73, 15, -152,160,171,147,252, 15, 31,216,143, 46,237, 90,225,204,169, 51,200, 47,186,126,167,124,229, 21, 16,159, 61, 70,121,124,130, 1, - 97, 3,240,199,110,207, 56,118,237,218,181,146,204,204, 76,213,197,139, 23,225,235,235, 11, 95, 95, 95,233,214,173, 91,213, 30, - 14,102, 82,165, 82,185,159, 33,126,135,206,209, 28,192,168,111,191,253,246,246,171,175,190,154, 44,147,201, 70, 42,149,202,228, - 7,177,131,135,135,135, 75,210,211,211, 89,255,110,201,240,193,146,222,161, 77, 85, 29,218, 21, 33,160,153, 15,120, 60, 63, 84, - 86,154, 80,172,169,196,100, 89, 79, 42,110, 54, 0,223,127,247, 51,171,126, 36,196, 13,188,240,204,227,170, 94,189,122,226,250, - 13, 45,142,255,121, 2, 21, 21, 58, 4, 4, 52, 69, 72, 72, 39,240,248, 66,152,205,249,136,157, 57,149, 38,172,253,241,111,101, -221,196,196,196,168,230,207,159,111, 63,159, 55,111, 94,131,121, 1, 30,100, 15,128, 82,169, 36, 50,153,140, 38, 37, 37,193,213, -198, 74,247,219,104,151,203, 99, 65, 8,193,186,117, 10,105, 76, 76,253,148, 0, 94,167, 23,237,228,157,177,188,137,203,193,180, -109,115, 30,130,131,120, 15,109,251,253, 83,225, 72,246,174,148, 2,183, 30,128,212,195,233, 0, 80,111, 69,224,240,156,156, 58, -239, 15,253,188,155,215,131,133, 67,142,115,143, 6,161,100,117,107, 8, 5, 66,116,108, 95,129,242,114, 33,142,159,233, 8, 62, -159, 15, 62,225, 67, 36, 52,161, 87, 55, 61,186,119,227,131,128, 7,145,208, 7, 34, 62, 65,216,227, 6, 4, 5, 90,176,241,127, -117,203,238,217,165, 13,174,228, 22,213, 36,127, 27,242,175, 93, 33,132, 39,160,237, 34, 31, 71, 96,243,166, 40,209,222,102, 85, -222, 53,107,214, 72, 86,172, 88,161,186,114,229,138,227,101,213,152, 49, 99,176,107, 23,123,107, 83,169, 84, 30,112, 36,127, 23, -104, 25, 31, 31, 95,242,198, 27,111,236, 67, 35, 79, 81,212, 65,254, 42, 79,202, 22, 26, 18,164, 10,110, 83,134,150, 45,252,209, - 33,184, 45,252,252,253,112,229, 74, 33,204,102, 11,130,219, 55,197,217,243,105,136, 28, 58, 72,146,118, 56,163,206,193,244,245, -215,167,210,199, 67,181,120,228,145, 14, 56,119,254, 10,142, 31, 63,143, 91,183,203, 65, 41, 16, 24,232, 11,189,190, 2,253,251, -247, 66, 73, 73, 41, 10,143,255,137, 33, 79,134, 75, 82, 15,177, 87, 84,107,134, 60,189, 0, 0, 32, 0, 73, 68, 65, 84, 30,100, - 48,214,191,109,219,105, 48,158,128, 53,107,214,120,236, 5, 96,166,251,157, 51, 1,187,216, 78,182,222,253,175, 67,135, 14,180, - 99,199,142,245,206,197,175, 84, 42,201,132, 9, 19,104, 98, 98, 34,152,141,149,234, 34, 60,219, 86,184,119,149, 63, 50, 50, 82, -194,108, 14, 84,139, 18, 75,221,200,180,255,111,185, 60, 86, 85,159,119,212, 89,222,160, 69, 21, 56,182,188, 73, 13,226,231,240, -112, 90,255,206, 46,255,122, 77, 1,212, 87, 17, 24,250,121,183, 90,149, 0,111,200,159, 65, 74, 74, 10, 10, 11, 11, 1, 0,193, -193,193,212,147,151,129, 79, 43, 33, 32,102,136,132, 66,252,121,166, 21,248, 2, 1,154, 10,117,214, 56,128, 38, 60, 20, 22, 54, -197,227,189, 44, 32,132, 64,246,172, 9,212,194, 3,136, 15, 8, 40,172,129,252,174,161, 47,185,138, 27,154, 10,100, 23, 22,214, - 90,150,146, 82, 13,180,183,110,216,100,177, 30,128,156,201, 31, 0,176,107,215, 46, 60,245,212, 83,146, 61,123,246,184, 29,224, -100, 50,217,240,188,188, 60,151, 29,166,180,180,212,241,114,243, 37, 75,150,224,220,185,115, 35, 30,164,169, 0, 7,242,103, 13, -201,240,193, 18,177,224, 58,124,125,155, 67,236, 35, 66,151, 46,157,209,177,115,103,148,149,169,161,209, 84, 64, 36,226, 35, 40, - 80, 12,129,111,115,183,131,169,128, 22,162,105,147, 22,208, 87,154,112,230, 76, 14,174,221, 40,197,245, 27, 21,168,172, 22,227, -145, 96, 19,196, 62,124,228,100,231,225,209,174, 93,113,237,122, 25, 42, 77,205, 88, 13,208,142,110,255,218,174,123, 58, 29, 80, -155, 76,111,100, 49,214,255,188,121,243,238,186, 62,127,254,124,175,188, 0,174,118, 39,116,158, 59,110, 40,175, 66, 90, 90,154, -170,190, 27,242, 76,152, 48,129, 42,149, 74,200,100, 50,184,154, 14, 96,227,169, 98,200, 31, 0, 50, 50, 50,238, 42,147,237,190, - 91,163,135,217, 97,176,161, 60, 46,137,243,253, 49, 97,181,206, 37,241, 7, 7,241,108,163, 20,187,230, 29, 61,122,116, 13, 47, -201,211, 79, 63, 93,163,174, 56,183,255,131, 3,143, 99, 0, 26,202, 35,208,144,200,201,177, 42, 22,133,133,133, 30, 41, 1, 2, -129, 0, 66,190, 16, 66, 33,193,176, 33,128, 94, 87,141, 75,185, 34, 8, 5, 66, 8,204, 2, 68,132, 83,136,132, 66,240,249, 60, -128, 18,104,180,192,177, 19, 2, 88, 44, 22, 0,183,106,149,123,226,207, 92, 84, 84,212,158,129,179, 75,219,182, 84,103, 34,168, -172, 44,133,217, 98, 98,253, 59, 79,156, 56, 81,187,210,161,215,179, 34, 26,103,215,191, 43,205,112,251,246,237,142,207, 39, 55, -134, 23,192,149,139,223,145,252,109, 3, 32, 59, 11, 48,184,141,138,199,187, 10,147,217, 2,131,209,132, 91,183, 53, 16,138,196, -168,174, 54,194,104, 50,195,100,178,192,100,166,172, 60, 49, 34,161, 14, 98,223, 14, 40, 46, 46, 69, 89,185, 30, 26,109, 37,154, -181,232,139,193,143, 63,142,140,212,221,104,111, 48,161,180,172, 20,221,187,119,133,143, 72, 0, 93,185,230,111, 49, 80,216, 34, -255,237,115,255, 78,158, 41,175, 98, 1,230,205,155, 87,195,155,224,124,143,173, 2,160,209, 68,219, 31,140,141, 13, 66, 98, 98, - 98,141,254,202, 24, 8,249,249,249, 94,239,202, 41,147,201,104, 98, 98,162,125,155,241,218, 98, 2,156,201,213,217, 83,149,150, -150,166, 98, 2,223, 40,165,244,232,209,163, 53,238, 31, 61,122, 84,229,206,233,193, 40, 13,140, 18,224,104,197,215,102,232,187, -249,109, 24, 31,153,140,205, 0, 38,174,214,225,137, 69, 21,245, 82,190,156,231,248,221,197, 4,112,184,247,222,128,218, 60, 0, -247,213,191,227,202,210,175,143,245,239,100,177, 34, 39, 39,135, 25, 80, 88,245, 94, 62, 95,128,136, 65, 22,240,121, 2, 28,203, - 20, 35, 43, 71,140,177, 79, 1,207, 60, 13,140, 27, 77,208,174,141, 8, 98,145, 15,196, 34, 31,248,138,125, 16,220,206, 7, 98, -145, 24, 98, 55,203, 0, 11,242,175,146, 18,205, 77, 82,219, 64,210,181, 75, 39, 4, 52,247,135,216, 98, 64,133,222,120,223, 59, -197,225,195,135,247, 31, 62,124,184, 6,225, 59,126, 0,160,184,184, 24,227,198,141,107, 52, 43,223,102, 29, 73,156,175,217,142, - 61,178,228,204,102, 64,167, 55, 66,167, 51,160,172,172, 26, 55,111,106,113,237,218,109,148,151, 87,163,162,194,136,138, 10, 3, -116, 58, 35, 74, 75, 74,221,202,170,174, 54,161,170,202, 12,163,209,128,166, 77, 69,232, 24,220, 12,126,254,254, 0,128,144,174, -157,209,161,125, 51, 4, 52, 19,131, 82, 51,140, 38, 11,170,171,117,127,139,129, 36, 38, 38, 70,181, 96,193,130, 58,201, 60, 38, - 38,134,181, 69,106,219, 82,184,214,251,171, 87,175,198, 55,223,124,227,241, 86,195, 14,219,206,218, 63, 12,161, 22, 22, 22, 50, -187,103,122,196,110, 19, 38, 76,160, 73, 73, 73,112, 84, 30,148, 74, 37, 25, 63,126,124,157,223,155, 57,115, 38, 8, 33, 96,250, -113,120,120,184, 4, 0, 34, 34, 34,164, 12,145, 51, 86, 63,115,159, 82,106,191,207,226,215,214,176,226, 93, 41, 14,108,102, 80, - 90,182,108, 9,226,160, 37,212, 87, 30,135, 7,143,252, 93,157,123,229, 1,120,144, 44,255, 59, 3,188, 25,124, 62,223,227,239, - 13, 25,100, 65,235, 86, 62, 40, 43, 19,192, 71, 96,130,143,136, 15,117,186, 8, 99,165, 66,136,132, 66,148,149, 9,145,154,233, -143,102, 98, 2, 30,143,135,209,209, 6, 60, 55,150,130,199,163, 88,122,210,243,114,202,100, 50,202,247, 19, 67, 35,108, 9, 63, - 99, 1, 46, 22, 82, 12,151, 12, 99,189,165,111,255,254,253,113,228,200, 17,151,247,252,252,252, 88, 15,150, 90,173,118, 4, 0, -172, 95,191, 30,211,166, 77,179, 95, 47, 46, 46,182, 31, 79,155, 54, 13, 69, 69, 69,141,210,158,233,233,233,106, 66, 8,152,121, - 82, 30,143, 7,198,221, 89,199,188,105,173,200,191,122, 77,218,170,153, 94,229, 35,226,195, 96,180,160,170,186, 0, 87, 11,138, -161,209,150, 65,163,209,163, 88, 83,137, 98, 77, 37,154, 7,117, 6,144, 91,167,172,155,183, 41,110,220,188,141,158, 61,187,162, - 68,171,133, 80,192, 67, 89,121, 1,116, 37, 22, 60,246,168, 14,109, 90,181,130,159,159, 31,124,124,124,113,253, 70, 57, 8, 63, -144, 85, 25, 29, 93,242, 13,181, 10,160,161, 87, 16,212,102,173, 3,119, 98, 1,216, 66, 46,151,171, 99, 98, 98, 48,119,238,220, -187,188, 10,204, 52,131,183, 43, 11, 38, 76,152, 80,195,130,101,222, 47, 66, 8, 94,124,241, 69, 36, 37, 37, 17,182, 74,128,179, -229,239,120,207,217,211,224,140,181,107,215, 18, 0,118, 43, 63, 35, 35, 67,101,235,215,106,155, 55,128,249,171, 2, 64,210,211, -211,237,247,235,218,206, 53, 45, 45, 77, 53,100,200, 96,233,145, 35,214,119, 98,230,204,153, 56,121,242, 79, 41, 67,225, 71,143, - 30, 85, 49,191, 63, 34, 34,194,173,167,108,237,218,181,248, 74, 26,136,137,107,244,214,223, 53,223,191,198,253,137,107,244,246, -250,156, 46, 21,226,187, 3, 6,112,120, 8,148,246,184, 21, 53,149,238,149, 11,113,242,228, 73,246,171, 0,238, 5,241, 59,198, - 2,212,199,250,175,105,201,215, 36,127,155,155,201,237, 84, 64,203,150,124,240, 8, 31,173, 90,242,209,173, 43,197,181,107, 2, -240,248, 4, 66,129, 0, 66,129, 16,127,157,246, 71,144,191, 16,124, 62, 31, 67,194,205,240,245,245,129,197, 66, 1,106,246,138, -252,155,180,233,136,155, 21, 20,186,139,106, 8, 8, 31, 23,175,229,147,139, 44,201,223, 54,176, 73,175, 94,189,170,186,122,245, -170,171,223,171,102, 89,142,145,197,197,197,251, 24,146, 7,128,113,227,198, 97,253,250,245,246,103,202,202,202, 80, 84, 84,132, - 29, 59,118, 48,203, 5,239,123,231,181, 13, 92,170,140,140, 12, 21, 19, 44,102,187,230, 49, 41,164, 30, 74, 87, 75, 37, 97,160, -133,101,208, 87, 26,161,245,169, 2,133, 22, 85, 85, 38,148,149, 85,163,232,182, 30,215,174, 87,224, 73,105, 39, 0,169,117,202, -170, 52,180, 68,222,165, 91, 8,233,242, 8,186,116,233,128,226,226,219, 8,108,110, 70,183,110, 1,104,221, 42, 4, 98, 95, 95, -148,148, 84,224,248,137, 11, 40, 40, 44, 67,219, 14,189, 30,218, 1, 36, 65,161,160,132, 64,202,112,169, 35,169,214,181,110, 63, - 65,161,144, 36,172, 93,203,202, 11,176,102,205, 26,149,179, 2,176,106,213, 42,172, 91,183, 78,234, 78, 94, 66, 66, 2,141,141, -141, 37,114,121,160, 67,153,168, 43, 98,166, 0, 48,126,252,120, 86,238,127,199, 41,133, 22, 45,146,224,237,180, 1, 99,229,219, - 20, 0, 74, 41,197,144, 33, 67,164,169,169,169,181,222,119, 71,216,204,220,122,106,234, 17, 21, 33, 4,132, 16,244,235,215, 87, -186,118,237, 90,245,221,207,222, 81, 50,220,201,227, 77,208,130,145, 39, 27,222,185,134,126, 52, 97,245, 57,187, 60, 54,224, 98, - 0, 30, 30,184, 85, 0, 30, 68,139,159,193,164, 73,147,234,245,125, 30,143, 7, 62,223,250,233, 25,202, 67,255, 62,102,248,136, -196, 86, 5, 64, 40,196,224,112,192,199, 7, 16,242,125,208,178,165, 24,124,190, 14,102,179, 5, 22,139,231,110,123,189,230, 6, -196, 29,122,224, 82,242, 79,104, 37,224,225,112,254, 21,143, 7,148,121,243,230,169,215,174, 93, 43,173,207, 50, 64,102, 89,223, -235,175,191,110,191,198, 88,250,101,101,101,208,235,245,152, 62,125, 58, 0,224,235,175,191, 6, 0, 85, 99,180,109, 90, 90,154, -218,102,237,171, 0, 96,208,160, 65,245, 10,224,234,208,169, 59, 50,143,238, 65,235,150,126,240,243,179,118,251,234,106, 51,202, -202, 13,208,104, 43,209,177, 75, 47,252,184, 97,163,219, 54,249,253,247,189,228,197,231, 35,232,209,140,179,120,114, 72, 95,116, -234,212, 9, 70, 67, 21,250,247,123, 28,254, 1, 1,184,146,151,143,194,107, 37, 72, 77, 59, 15,109,121, 0,118,175,223,248,208, -250, 76,103,198,202,109,237, 79, 48, 83, 46,183, 47, 11,183, 56,145, 62,143, 71, 0,106,167, 12, 58, 83, 46, 71, 95, 23, 22, 44, - 33,160,112, 80,203, 99, 99, 99,225,236, 5,152, 59,119, 46, 8, 33,136,141,149,171,108,124,142,153,177,114,244,237,123,183,188, -216,216, 88,187, 59,222, 29,201,177, 37,127,103,140, 31, 63, 30, 35, 70,140,144,122,171, 4, 59,206,213,135,135,135, 75, 83, 83, - 83,213,181,221,103, 19,164,104, 91, 85, 64, 25,229, 43, 50, 50, 82, 42,151,199,170,157,149, 14, 7,249,240, 68, 94,226,252, 38, -214, 83,113,155, 59,158,142,249,249,118,133, 96,207,169,186,199, 62, 87,121, 0,184, 24,128,135, 84, 1, 24, 60,100,208, 61,153, -243,105, 40,203,223,177, 35,121, 3,141,150,160, 93, 27, 30, 8,225,129,240,120,216,187,223, 58,191,239,227, 35,134,143,200, 7, -227,158, 38, 16,251,136,224, 43, 38,208, 20,243,145,113,188, 41,204, 22, 51, 58,118,240,108, 94, 87, 38,147,209,107, 5,151,160, -205,220,133,110, 29,133, 56, 83,232,253,188,240,204,153, 51,213,168,103, 80,158, 76, 38,147,126,249,229,151, 42,198,205, 95, 92, - 92, 60, 49, 60, 60,188, 98,223,190,125, 59,159,123,238,185, 81,197,197,197,100,234,212,169,123,108,249, 2, 26,173,115,166,167, -167,171,195,195,195,165,204,113,125,100,253,184, 97, 35,153,250,202,100,154,125,225, 28,174,229, 93, 1,143, 71, 96, 54, 83,136, -125,131, 16,218,179, 55,118,255,145,204,186, 78,175,221,178, 72, 53,197,215, 84, 85, 85, 38,244,233, 29,130,224,246, 45,145,127, -245, 38,180,167,115,145,149,157,143,253, 7,254,194,149, 66,138, 99,153,103,188,106,167, 7, 37,249,143,101,115,160,215,207,245, -255,132,165,188,220,255, 97,205,154, 53,118, 5, 96,205,154, 53, 64,222,250,187,158,117, 37,143, 45, 40,165,164, 62,253, 56, 54, - 54,182, 94,125,207,129,228,213,222,220,119,229, 85,112,252,174, 43,121, 30,181,243,149, 45, 72, 90,243,178,117,108, 24,254, 72, - 13,242, 7, 0,217,152, 39,172, 7,218,147,110, 21, 0, 46, 15,192,131,131,117, 43, 23,222, 53, 13,224,145, 2,240,128, 7,124, -212,187,112,153, 39,124, 32, 22,137, 48,110, 12, 1,143, 16, 12, 26,104,194,233, 51,190,224, 17,235,156,127, 73, 9, 15,237,219, -242,193, 35, 34,156, 58, 45,130,216, 7, 48, 24, 13,184,146,239,235, 17,249,231,102,255,137,240, 17,207, 64,208, 50, 28,185,217, - 25, 16,220, 72, 66, 64,179, 32, 90, 90,166,105,148, 10, 86, 42,149,106,153, 76, 38, 29, 56,112,160, 42, 46, 46, 14,189,123,247, - 46,210,106,181, 24, 56,112,160, 84,171,213, 98,206,156, 57, 42, 27,249,171, 27,187,145,235, 75,252,206, 74, 0, 0, 68, 14, 29, - 36,105,215,182,157,202,223,223, 31, 63,110,216, 72,206,156,205,245,108, 64, 79,205, 80, 3, 32,102,180,164,231,178,210,209,174, - 77, 19,136,197, 66, 84, 84, 24, 80,120,189, 12, 68,208, 17,199, 50, 83,185,104, 41, 54, 56,241, 6,208,245,255, 80, 99,121,225, -241, 5,141, 90,164,216,216, 32,135,180,181, 13, 67,104,238, 72,217, 19,210,174,111, 62, 3, 87,227,188, 44,210,199,250, 91, 43, -175, 91, 63, 28, 30, 90,244,235,215,207, 30,240,183,110,229,194,187,238,185, 85, 0, 26, 58, 31,255,253,206,239,239,153, 22, 65, -160,213, 18,248,181, 37,104, 17, 68, 48,112,128, 17, 98, 17, 31, 62, 34, 35, 90, 4,137,109,131, 0, 65,196, 64, 51, 50, 78, 8, -173,222, 2,150,138,145, 76, 38,163,189,186, 55,195, 27,115, 63, 66,165,168, 3,126, 77, 46, 68,215,208, 65, 0,128, 38,199,118, - 32, 59, 31,180,162,188,241,148, 0, 0, 36, 47, 47, 79,178,114,229, 74,149,163,119, 0, 0,105, 76,203,255, 94,195,150,236,167, -222,245,126,240,208, 9, 50,245,149,201,244, 86,241, 45, 84,222,208, 67, 44,110,129, 14, 93, 30,103, 53,149,240,176,195,154, 14, -187,129,126,102,222,122,216, 87, 4,228,109,104,244,223,230, 46,184,239,239,134, 81,207, 76,108, 80,203,157,139, 1,120,176,148, -128,218,200,223,173, 7,224,159, 0, 10,107, 84, 63,225, 81, 80, 80, 4, 53,167, 72, 57, 44,128, 88, 36,132,143, 72,128,103,199, - 80, 80,106, 65, 96, 11, 19, 76,102, 2,139,197,108, 27,252,220,227,241,206, 21, 24,251,162, 12, 21,130,110,104,221,196, 31,147, - 95, 8,194,198,173,167,237, 74,128,209,252, 43, 78, 95,104,220,117,226,140, 34,224,112,206,189, 61, 94,120, 21,254,142, 32, 19, -180,132, 38, 6,222,205, 12,202, 32,175,228,173,211,174, 64, 76,224,194,187,111, 28, 95,208,232, 86,255, 63, 25,251,254, 50, 54, -100, 31, 38, 86, 5,145, 58, 40,139,220,180, 64, 99, 41, 1,110, 27,203,219,125,132, 57,112,224,192,129, 3, 7, 14, 15, 47,184, - 68,207, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56,112,224,192, 41, 0, - 28, 56,112,224,192,129, 3,135,191, 7,106,172, 2, 56,121,242,164,215,209,160,174,130, 9, 27, 90,222,148,233,177,110,191,167, -211,220,176, 31,251, 7,181,181, 31,255,252,125,194, 93,207,182,146,190,234, 86,222,190,213,119, 50,230,141,156,255,165,253,248, -150,234, 91,120, 83,190,218,224,109,249,106,131,171,242, 61, 63, 85,238,246,123,153,170,157,232,220,185, 51, 46, 95,190,140,129, -210,177,246,235,191,253,168,184,231,245,231,174,191,196, 7, 7, 75,222, 40, 44,116,204, 76, 72,238,103,255,115,150, 55,118,236, - 88,201,174, 93,187,106,100, 74, 28, 51,102,140,116,231,206,157,234,198,120, 63, 30,100,121,245,145,245,119,174,191,168,168,168, -151,250,244,233,179,241,244,233,211, 47,166,164,164,252,218, 0,229,163, 15,202,251,193,201,107, 92,121, 30, 43, 0,206,248,234, -171,175, 36, 85, 85, 85, 32,124, 33, 8, 33, 48,155,140, 16, 9, 5,152, 51,103,142,186,190,154,199, 87, 95,125, 37, 1,128,217, -179,103,215, 75,150, 78,115, 3,254, 65,109,237,196,223,182, 99,103, 0,192,141,171,151,189,146,183,111,245,235, 24, 57,255, 75, - 59,113,125,181, 45, 3, 0, 48,251,217, 65,127, 75, 13, 48, 83,181, 19, 3,165, 99,145,169,218,105, 37,181,241, 83, 0, 0,151, - 47, 55,126,253,133, 2,146,108, 64, 21, 10, 72,179, 1,213, 27,133,133,200,136,123, 27, 0, 48,104,229,167,141, 90,111, 47,189, -244, 18,221,180,105, 19,170,170,170,106, 92, 23,139,197,170,151, 94,122, 9,191,252,242,203,131,186, 60,112,104,247, 46,193, 27, -168,217,172,207,206,191,177, 8,192, 14,206, 14,170, 29,159,127,254,249,240, 63,255,252,179,217,181,107,215,218, 6, 5, 5, 53, - 15, 11, 11, 43,124,243,205, 55,127,244, 86, 94, 84, 84,212,136,201,147, 39,167,108,220,184,241, 85, 0, 1,147,254, 47,118, 58, - 0,203,233,211,167, 95, 86, 40, 20,191,201,229,114,139,135, 34,153,228,202,180, 1,198, 43,103, 18,105,168, 62, 76,239,129, 76, - 14, 13,237, 1,112,196,127,254, 27, 47, 9,232,216, 71, 21,213,167, 7,252,124,132,160,148,194,108,166, 56,147,115, 5,241,171, - 63,147,250,250, 8, 49,107,214, 44,175,200,251,231, 13,139, 36,189,186, 29, 84,157,201, 14,145,122, 91,112,134,240,125, 3, 90, - 64,167,185, 97, 39,254,186, 60, 2,108, 44,213, 65, 83, 22, 98,223,234,215,237, 47, 82,109,207,213,181,198,210,249,127,138, 68, - 34,235, 91, 64, 41, 44, 22,235,251,109, 54,155,237,229,231,241,133,172,173,104, 0,104,215,218,154,170,211, 80, 86,130,106,147, - 9, 0, 80, 97,178,202,235, 50,106, 6, 30,237,213,159, 21,241, 3, 64,223,193, 35,144,169,218,105, 39,254,218,158,187,159,245, -199, 12, 26,217, 0,158,242,247,199, 30,157, 78,197, 16, 63, 0,100,237,221, 87,215,160, 85, 39, 62,253,105,153,228,248,237, 99, - 40,204, 63,133,110,157, 34,240,191,185,191,120,220,135,199,142, 29,251,220,230,205,155, 25,242, 55, 1,168, 2,224, 7,192, 82, - 85, 85, 37,240,245,245,197,216,177, 99, 37,174, 60, 1,141,140, 54, 79,244,235,243,199,158, 95, 18,154,232, 10,207, 99,168,108, -230,198, 43, 90,227,203, 0,126,123,208, 6, 38,153, 76, 70,189,221,128,199,137, 24,189,194,151, 95,126, 41,201,200,200, 80,109, -216,112, 39, 49,209,237,219,183,145,157,157,141,103,158,121,230, 7,137, 68, 34,125,243,205, 55, 89,181,175, 66,161,224,109,220, -184,241, 67, 0,255,159,189, 47,143,111,162,234,222,127, 38, 73,211,116,223,217,247,150,202, 78,161, 8,200,154, 0,165, 66, 1, -101, 41, 90,208, 87, 68,104, 64, 69, 1, 81,180,175,223,159,190, 46, 8,138, 20,101, 13,139,226,171,101, 43,136, 82, 40, 20, 10, - 41,101,211, 74, 41,101,183,180,165,116,163,116, 79,151,236,153,249,253,145, 76, 76, 67,210, 76,210,176,190,243,124, 62,243,105, -231,206,228,100,114,231,222,251,156,115,238,185,231, 62, 55, 34,242, 69,183,157, 59,119,182,126,249,245, 5, 94, 0,116, 0,218, - 26,110,123, 6, 0,103,244,232,209,163,128,251,183, 58,183, 70,170,131,103,127,136,140,132,149,148,181,254,102, 71,255,160,210, -207,103,128,203,229, 65,167,211, 66, 86,223,128, 89,211, 95,160,234,235,235, 91, 74,216,148, 51,223, 11, 11,219,176,180,237,175, -137,167,192,182, 2,176,102,237, 58,161,112,226, 12,105,199, 86, 62,112, 23,240, 64,146, 36,116, 36,192,227, 18,240,247,233,129, -222,221, 59, 73, 83, 83, 14,139, 54,110,220, 40,180, 87, 9, 88,183,110,157,176,103,240, 89,105,255, 30,183,193,229,232,164,235, -214,175, 23, 45,122,251,109,187,100, 52, 86,151,193,205, 39, 0, 62,222, 94, 0, 96,252,107,233,190, 54, 29,187,216,244, 6, 28, -143,127, 27,131,103,127,136,215, 94,154, 6, 0,198,191,150,238,219,112, 48,195, 46,237,154,203,229,162, 67,135, 14,224,114,185, - 80,171,213,104,108,108,132, 78,167, 67, 77, 77,141, 67, 47,215,147,199,197, 15,107, 15,192,213, 7,184, 87, 0,252,213, 80,130, -138,178, 92,252, 28,255,145, 93, 86,127,255, 97, 99,209,161,157,126,138,164,131, 5,242,239,210,165,139,113, 58, 0, 0,138,139, -139,157, 82,127, 12,147,171, 82,145, 30, 30,248,252,237,183, 0, 0,159,155, 16,255, 47, 57, 57, 77, 7, 19, 59,178,181,206,250, -104,164,176,102,112,170,244,195, 78,175, 64, 69,142,131, 43, 73, 33,226, 5, 29,126,252,102,175,232,248, 6, 48, 29,204,121, 11, - 22, 44,248, 77,161, 80, 96,199,142, 29,202, 57,115,230, 8, 0,120, 2, 32,119,236,216,161,158, 51,103, 14, 79,161, 80, 64, 32, - 16, 72, 91, 58,208, 69, 70, 70, 10,143, 29, 59, 38, 53,108,216,210, 98,120,242, 57,255,111,221,231, 31,184,249, 94,223, 5,183, -191, 79,226,211, 49,126, 94,239, 36, 85,124, 86,175,166, 30, 43, 5,128,222,130,183,166, 38,130,242,247, 79,181,251,183, 15, 25, - 50, 68,248,231,159,127, 58, 76, 54,107,214,172, 17,238,219,183, 79, 90, 95, 95,111,241,250,221,187,119,177,111,223, 62,233,235, -175,191, 46,250,241,199, 31,211,108,180, 23, 98,231,206,157, 63,143,136,124,113,102, 78,214, 57, 94,135,118,109,180, 47,191,190, -160,201,184,123,242,240,175,232,219,183,111,143,157, 59,119, 78,232,219,183,239, 65, 0, 56,115,230, 76,179,253,131, 73,127,211, -247, 15, 2,176,145,136,103,192,128, 1,212,145,148,227,200,186,122,221, 88,166, 84,170,240,245,186, 45, 13, 11,231,196,176,132, -253, 20,227,190, 32,192,213,171, 87, 11, 71,140,159, 42,237,209, 41, 0,174, 46, 28,144, 36,137,178,178, 50, 92,201,206,130, 90, - 75,130, 36, 41, 4,248,184, 99,252,132, 73, 82,133, 74,107,247, 23,186,186,148, 35,184, 83, 25,192, 37,208,171,123, 17, 92,121, -247,236,182,252, 77,201,223, 28,178,186,122,148, 21, 21,192,205, 39,192,170, 87,160, 57,242, 50,199, 79,123,126,197, 91, 83, 6, - 99,240,236, 15,209,140,150,125, 31,248,124, 62,184, 92, 46,188,189,189,145,159,159,143,154,154, 26,189, 34,229, 32,249,183,109, -213, 26,158, 60, 46,166, 46,250, 2, 19,102, 13,195,161,171, 37, 40, 83,160,197,228,111,142,226,210, 50, 92,187,112, 22, 65,126, -222,122,242,231,113,157, 82,127,207, 79,127, 13, 0,224,199,115,177,139,252, 1,224,255,214,111,192,255,173,223, 96, 36,255,148, -198, 70,188, 63,126,146,254, 98, 16,159,209,239, 30, 22,215, 85, 56,255,189,231,164,175,119,126, 19, 46, 28, 79,120,192, 29, 28, -112,209,190,245,112,188,253,249, 82,233,242,164, 30,140,212,136,180,180, 52, 13, 0,252,244,211, 79,114, 0, 2,122, 27,229, 29, - 59,118,144, 0,220, 77,183, 85,142,137,137,113,104, 94, 46, 62, 62, 94,104, 79, 57, 3,140, 24, 52,160,191, 60,241,215, 3,226, - 1,125, 66,185,141,215, 79,160,160,188, 30,119,107,229, 32, 41,202,161, 64, 96,138,162,168,234,234,113,212,168, 81,163,156,154, - 72,204,132,252,225,239,159,234,144,140,140,140, 12, 41, 0,130, 32, 8, 12, 25, 50,196,238, 58, 75, 77, 77,189,143,252, 47, 92, -184,128, 89,179,102, 25,207, 53, 26, 13,110,222,188, 41,141,143,143,111,214,139,185,115,231,206,183, 71, 68,190, 56,233,203,184, - 37,188,196,196, 68,108, 91,183,154,103,240, 24, 25,201, 63, 49, 49, 17,235,215,175, 71,223,190,125, 15,218,234,111,230,228,111, -173,191, 77, 24,110,240, 2,122,121,216,148,247,237,186, 77, 70,242, 47,175,172, 66,121,101, 21,100,245, 13,112,113,225,121,110, -218,177, 75, 9,103,109,136,192,226,161, 34, 44, 44,236,190,163, 89, 5, 96,227,198,141, 84, 64,151,126,232,210,198, 23, 74,141, - 14, 4, 1,164,164, 28,197,127,127,218,129,203,217,217,120,127,233, 98,112,185, 28,144, 58, 18,222,238,174,232,210,111,132,116, -237,218,181,140, 59,216,250,245,235,133,189,187,223,145,122,123,202,241,195, 79,229,224, 16, 20, 6,247,253, 91,186,126,253,122, -187, 58,169, 37,242,167,137, 95, 33,171,106,162, 32,200,234,234,109,202,179,212,153,232,142,148,145,176,178, 9,193,253,180,231, - 87, 70,207, 24, 28, 28,140,128,128, 0,212,213,213,129,207,231,131,195,225, 64,161, 80,160,166,166, 6, 92,174,190,147,219,179, -217,210,254,223, 14, 96,241,218, 99, 56,176,238, 99,180,109,213, 26,238, 30,254, 40,210,149,224,231,248,143,224,105, 24, 52,184, - 12,229, 89, 34,127,154,248,101,165,121,232,209,161, 21,234,229, 74,184,186,187, 2, 58,157,205,120, 0, 91,245,247,209,214, 67, -184,118,241, 60,250,116,235, 5,153,206,182,210, 72,147,255,223,199,142,227,255,214,111, 48,150,167, 52, 54, 34,165,177, 17,249, -226,255,224,216,245,203,232, 61,184, 27, 80,101,123,107,230,209,203,186, 9, 23,190, 51, 86, 26,228,209, 19, 10,170, 30, 80,149, -131,175,170,134, 74, 87, 15, 37,169, 0,201,247, 68,251,145,131, 16,177,176, 51,101,203,154,163,231,253,197, 98,177,187, 88, 44, - 6,244, 83, 0, 16,139,197, 48,156, 27, 44, 40, 37,118,239,222,109,119,167, 93,178,100,137,112,233,210,165,210, 94,189,122, 81, - 4, 65, 72, 1,224,149, 87, 94,161, 58,119,238, 76,125,252,241,199, 14,109,205,236,229,202,217,177,225,195,215,221, 34,219,171, -184,231,110,150,225, 80, 1, 7, 31, 30,185,167,250, 79, 90,131,172, 81,131,215, 28,145, 89, 83, 19,241, 32, 45,127,248,251,167, - 98,246,236,217,118, 79, 17,154, 18, 62, 69, 81, 4,189,157, 52, 83,188,246,218,107,194,123,247,152, 25, 37,106,181, 26, 87,174, - 92, 57,217, 92,123, 1, 32,236,208,174, 13, 63, 58, 58, 26, 0,144,153,153,137,147,135,127, 21, 20,151,150,145, 52,249, 27,126, -187,177,191, 93,185,114, 37,190, 37,253,237,235, 57,147,112, 53,175, 8,109,186,181, 5, 26,229,140,127,123,121,101, 21, 52, 26, -173, 65,193,209, 66,163,209,162,232, 78,129,160,133,175,149,176,113,206,226, 17,162,137, 43, 74,165, 82, 97, 64,143, 30, 82,119, - 55, 23,144, 36, 5, 29, 9,156, 61,125, 6,255,249,252, 11,144, 20,112, 43, 55, 23,151,179, 47,161, 79,159,254,224,114, 9, 60, -211,173, 3,242, 47, 50,247, 2,240,121,229, 8,237, 82, 10,240, 8, 20,221,213, 0, 60, 2,253,122,220, 65,198,149,114,135,127, -128,169,123,223,146,103, 64, 33,171,106,178, 26,192, 22, 76,221,251,150, 52,237,140,132,149,136, 88,178,222, 98, 20,187, 41,180, - 90, 45,220,221,221,193,225,112,224,231,231, 7,185, 92,142,198, 70,253, 54,192, 65, 65, 65,168,170,170,178, 43, 71,182,178, 6, - 24,236,230,134,247,215,157, 70, 68,127,224, 78, 22,240,151,225,218,251,235, 78,227,251, 37, 34,232, 72,157,221,245,119,237,194, - 89,227,255, 99,195,123,128,231,197, 65, 74,218,117, 12,232,209, 17,222,158,174,248,105, 95, 42, 6,137,162, 80,108, 97, 21,128, -173,250, 59,120,157, 2,238, 2, 83,198, 18,216,122, 40, 31, 1,126, 93, 49,109, 56,193,168,254,104,119,127, 74,227, 63, 91, 39, - 83,159,198, 3,237,101, 32,230,127, 2,234, 63,159, 3, 28, 5,136,140, 21,244,160, 98,181, 50,131,167,123, 74, 59,251,134,163, - 78,215, 0, 85, 77, 46,126, 46,220,137, 51, 83,106,208,107,158, 8,227, 23,121,194,205,239, 25, 8,120,126,224, 77,145, 97,158, -118, 30,181,109,235, 54,139,131,148, 88, 44,166,104,165,141,195,225,128,162, 40,181, 65,137, 86,114, 56, 28, 57, 69, 81,254, 0, - 72,180, 96,121,109,124,124,124, 90,100,100,164,168,170,170, 74,154,146,146,162, 87,124, 82, 82,208,179,103, 79,244,232,209, 67, - 68,151,217,131,122, 21,249,206,220,255,251, 62,233,155,168, 54, 28, 74, 41,195,252,132, 28,141, 86,163, 89,175,210, 97, 5, 0, -135, 54,163,120,241, 69,245, 3, 39,255,132,132,132, 52, 71,172,127,211, 41, 19,130, 32, 48,120,240, 96, 33,211, 93, 37,117, 58, -157, 93, 10,195,237,219,183, 33,145, 72,136, 77,155, 54, 89,186, 44, 0,208, 11, 0,111, 76,212,180,218,252,252,124,223,204,204, - 76, 36, 38, 38, 34, 60, 63,159,147,153,153, 9, 0, 8, 15, 15,199,243,163, 7,193,219,211, 21,235,127, 60, 80, 62,107,214,172, -184, 77,155, 54, 45,177,183,191,221,253,109, 37,188,122, 11,224,217,125, 49,246,174,156,135,254,125,218,224,153, 73, 95,216,236, - 31,178,186,122, 8, 4,174, 0, 0, 23, 23, 30,228,114,165,179,121,134, 37,253, 71, 0, 38,155, 1, 53, 25,168, 72,146,132,187, - 43, 31,106, 45, 5,146, 2, 56, 4,240,201,103, 95, 64, 71, 2, 13, 13, 13, 40, 43,187,139,214,173,219,128,162, 72,104,181, 58, - 8, 92,120,224,186, 48,115,193,110,216,176, 65,216,189, 75,177, 52,208,175, 78,223, 28, 12, 7, 65, 80, 24,216,251,150,148, 94, - 21, 96, 15,104,235,158,118,247,155,147, 63, 19,235,223, 92,139,166,137,127,195,193,140,251,200,159,169,245, 15,232, 3,134, 92, - 93, 93,225,227,227, 99,116, 25,210,129,127, 62, 62, 62,104,211,166, 13,180, 90,230,202,211,143,169,167,224,211, 5, 16,134,234, -207,115,180,122,247, 63,160, 47,251,248, 11, 41,106,213,246, 77,201, 20,151,234,131, 21, 59,181,242,135,151,143, 7,120,222, 92, - 40, 43, 21, 0,135,131,182,157, 59,224,108,118,129, 67,245,247,218,123, 95, 98,212,208, 49,224,149, 1, 13,173, 1,119, 14, 7, - 67,187,116,133,120, 74,107, 70,114,204,231,250,127,121,105, 30,166,190, 56, 18, 8, 81, 2,151,121,128, 39, 15,152, 28,142, 14, -155,183, 50,243,198,180,247,135, 90, 93, 13, 66, 85,133,159, 11,119,226,252, 28, 31,140,154, 58, 7, 35, 90, 61, 47,186,122, 76, - 11, 45,217, 8, 23,117, 35,180, 61, 72, 84,220, 99, 22, 52,106, 80,222,148,115,230,204,225, 0,168,161, 12, 59, 68, 25,206, 91, -132,148,148,148,180,158, 61,123,138,220,221,221, 17, 24, 24, 8,119,119,119,164,167,167, 19, 41, 41, 41,105, 14,136,107, 51,105, -210,164,173, 27,182,252,192,249, 36,173,129,220,119, 46, 23, 42,181,166, 81,169,195, 50,123,200,223,220,229,159,158,158, 78,208, -199,227, 66,254,150,220,253,246,122, 1, 26, 26, 26,140,255, 95,184,112,193,120, 0,192,210,165, 75,155,156,155,220,239,106, 69, - 92, 59, 0, 93, 12, 74,161,251,243,211, 95, 81,154,122, 2,104,203,255,185,225,195, 77,251,219, 33,177, 88,172,180,167,191,197, - 78, 30,133,126,225, 61,224,213,223, 11, 37, 39, 10, 1,129, 43,166, 47,250, 23, 6,191,250, 61,163,223,172,213,234, 80,114,247, -158,150,182,252,105, 20,221, 41,104,233,171,165,172, 28, 44, 30, 3,133, 0,150, 44, 21,202, 48,184,145, 20,160, 35,245, 74, 0, - 65, 0,191,238,223,135,169,211,102, 32, 48,168,149,113, 0,164,236,120,151, 92, 78, 57,122,135, 20, 25,207,251,245,113, 55,234, -134, 3,123,229,131,203,177,223, 11, 96,238,238,183,116,221, 30,235,223,220,221,111,233,186,233, 90,246,230, 80, 87, 87,135,250, -250,122,168, 84, 42,144, 36,137,138,138, 10,163,251, 95, 46,151,163,161,161,193,174, 41,128, 3,235, 62, 70,218, 85, 64, 86, 0, -104, 20,192,247,203, 69, 70,247,255,197, 44,224,210,221,179,224,218, 89,127,178,210, 60,248,251,120, 32,192,223, 3,207,132,246, - 68,254,237, 10,228,148, 84,161, 83,128, 15, 84,247,202,145,123, 43,183, 73, 46, 0, 38,245, 55, 76,248, 2, 70,136, 98,112, 32, -105, 47,164,233,123,177,115,205,123,152,254,222, 10, 92,214, 0, 21, 85,229,140,234,207,116,174,255,245, 97, 67, 48,187, 87,103, -236, 61,112, 18,151, 47, 23, 96,205,149, 76,236,142,248, 23,176,253, 28, 74, 74, 42, 24, 89, 23, 29,148,174,208,169, 43,161, 86, -235, 35,171, 91,183,239,136, 30, 61,123,138,234,220,244,177, 24, 10, 82, 14,142,170, 17,110,141, 92,220,187,219,188, 2, 64,191, - 51,165, 82, 9,165, 82, 41, 0,160, 6,224,165, 84, 42,189,205,151, 4,182,192, 11, 32, 76, 79, 79,151,246,236,217, 19,175,188, -242,138,168,178,178, 18,211,166, 77,179,103,224, 28,193,231,243, 27, 60, 61, 61,181, 17, 17, 17,119,151, 47, 95,222, 46, 46, 46, - 46,255,175,172,203, 19,119, 95, 83,221,212,144,176,123, 63,214, 7,225,242,119, 38,249,155, 91,255,180,194, 66,191, 51,166,177, - 0, 46, 46,255,196,168,172, 89,179,198,120, 88, 58, 7,140, 43,124,172,189, 27,190,225,224, 0,224,201, 74,243, 44,186,211,233, -254,150,117, 49,235,246,172, 89,179, 98,237,233,111, 35,159,125, 6,227,134,135,226,203,207, 86,227,219,181,201,248,127,191,156, -196,130, 49,131, 80,246,123, 50,100, 53,117, 76,250, 7, 17, 61,229,121,104, 52,218, 44,141, 70,171, 53, 85, 0, 0, 96,197, 39, - 31,181,196,130,103, 45,255, 71, 8, 75,115,255,230, 74, 64, 19, 5,128,195,225, 64,214, 32, 7,151, 67, 64,171,213,129,164, 40, -104, 73,125, 16,105,246,165, 44,140, 25, 27,169,119,147, 81, 20,184, 28, 46,234,229,106,104,213, 42,219,214,255,198,141,194,174, -237,239, 74,131,252,101, 70, 45, 99,216, 96, 79, 67,140, 46, 1,130,160, 48,160,103,174,116,195,198,141,140,189, 0,180,117,223, - 92, 48,160, 67,214,107, 51,193, 53,246,192,207,207, 15, 21, 21, 21,112,117,117, 69,125,125, 61,130,130,130,140, 65,129, 74,165, - 18,181,181,181,118, 41, 0,177, 95,238,198,247,203, 69,240,233, 2,164, 93, 5,222, 89, 37,133, 39,143,139,105,239,126,133, 98, -178, 12, 9,107, 62, 0,151,195, 92, 30,109,253,135,135,135, 34,168, 91, 23,180, 10, 10, 4,159, 67, 64, 75, 80,168,104, 84,160, -166, 94,233, 80,253,125,187,242, 55,188,216,179, 43,188,189, 3,224, 30,212, 14,154,234, 26,100, 29,218,133,218,234, 66,135, 26, -241, 15, 43,223, 6,150,140, 3, 79,171, 70,151, 70,160,156, 91,135,239,239,254, 5,240,189, 25,203,184,152,244,135,168,146,163, - 64, 33, 95,142, 65, 33, 34,244,250,151, 39,242,253,210,164, 65, 65, 89,210,142, 67,243, 33,227,212, 67, 69, 41, 32,255,133,132, -192,211,139,137,229,111, 58,192,211,171, 0,248,206,234,184, 71,143, 30, 5, 0,204,158, 61, 91, 20, 31, 31,159, 54,117,234, 84, -163,197,200,132,252,131,130,130,142,108,221,186,213, 67, 34,145,112,151, 44, 89,130,197,139, 23, 83,231,206,157, 27, 10, 32, 69, -161, 69, 79, 0,127,218,251, 76, 98,177,159, 85,183,191,163, 1,129,206, 36,127,115,130, 55, 85, 88, 40,138, 34, 12,129,129,182, -251, 69,113,241, 57,250,255,157, 59,119, 26, 15,243, 50, 26,254,254,254, 16,139,197,214, 6,193, 98, 0,181, 0, 56,197,165,101, - 56,127,254,188,113,206, 63, 60, 60, 28,128,126,251,237, 61, 7,147, 81, 83,175,148, 3, 88, 33, 22,139,117,246,244,183,223, 15, -124,138,200,229,139, 48,113,226, 88, 4,186,114, 81, 79, 80, 72,201, 41,194,249,171, 37,118, 17,245,194, 57, 49,207,230,231,230, -242,138,238, 20,128, 62, 12,228, 15,214,106,127, 50,137,223,188,204, 18,154,196, 0,184,186,186,226,214,245,203,162, 46,237,252, -165,110, 46, 60,232,116, 36, 8,130, 0, 65, 0,177,226,183, 64, 81, 36,116,134,124, 0,114,165, 18, 55,114,242,193,231,219,140, -234,134, 86, 83,141, 1,189,110,155,142, 24,120,115,201,109,236,255,165,187,177,105, 13,234,147,135, 63,178,123,218,109,253, 91, - 34,126,133,172, 10, 0, 28,178,254, 45,117,180,140,132,149, 0,192,216,250, 7,244,235,252,219,180,105, 3,149, 74,133,123,247, -238, 65,167,211, 33, 48, 48, 16, 85, 85, 85, 8, 12, 12, 52,212, 43,115,194,174, 40,203,197,199, 95, 72, 33, 43, 0,190,121,111, - 36, 26,180, 58, 44, 93,149,136,239,150, 71,227,189, 53,135,192, 35, 8,216,193,255,144,149,230,161,109,160, 47, 92,224, 2, 29, - 8,220,189,125, 13,119,202,101, 8, 14,242,199,239, 23,207,225,198,117,216,109,253, 79,159,187, 20, 46,254, 0,135, 11,236, 72, -190,141,253, 27,223,199,220,149, 18, 44,157,220, 31,111,141,237,108, 87,253,165, 52, 54,226,219, 41, 51,129, 90, 1, 64,184, 0, -223,174,198,140,191, 78,227,216,216,133, 32,190, 90, 4,226,143, 15, 24, 91, 24,151,238, 6, 96,136, 66,134, 6, 55, 46,228, 2, - 1,130,167,187, 64, 69, 41, 32,227,184, 64,139, 80, 80, 58, 57, 52,149,119,113,118,157, 12,179,103, 5, 35, 77, 42,125,232,157, - 54, 54, 54,150, 2,128, 45, 91,182,208,174,126, 98,201, 18,253, 52,240, 47,191,252,194,244,205, 14,111,215,174,221,209,175,190, -250,202,227,214,173, 91,112,113,113,129,183,183, 55, 46, 95,190,172, 1, 80,209,146,231,107,110, 77,190, 35,222, 1,103,146,191, -185,245,175, 39,230,251,151, 15, 26,150, 7,166,217,120,174, 91,123,246,236, 25,198,116,122, 78, 32, 16,204,181,174, 52,137,235, - 71,143, 30,125, 27, 64,120, 78,214, 57,152,206,249,191, 57,119, 38,142,118,235,134,196,196, 68,100,102,102,226, 72,183,110,238, -179,102,205,250,241,212,169, 83,140,251,219, 75,227,134,192,135,244,131, 28, 46,216, 31,191, 8, 27, 15, 93,194,251,207,143,192, -156, 53, 59, 49, 99,197,207,246, 90,224,196,138, 79, 62,178,148, 8,136, 50, 81, 2, 88,139,254, 41, 67, 19, 15,192,155,111,190, - 73,212,222,205, 69, 94, 81, 21,120, 46, 92,104,117, 36, 52, 90, 29, 46, 94,204,196,127,255,251, 35,212, 58, 10, 26, 29, 74,253, -203,119, 0, 0, 32, 0, 73, 68, 65, 84, 9, 62,143,131,242,154, 6,148,220, 56, 47, 90,188,120,113,179, 29,106,227,198,141,194, -158,193,119,254,177,254, 13,237,106,255, 47,161,250,246,196,161, 0, 14, 5, 14,135,196,208,254, 55,164, 27, 25,120, 1, 44, 89, -255,166,171, 0, 60,252,219,216, 69,254,150,172,127,211,168,218,136, 37,235,237, 34, 47,253,160, 88,131,134,134, 6,184,184,184, - 24,173,127,146, 36,141,127,237, 85, 0,126,142,255, 8, 23, 75, 78,193,179,141, 62,232,207,139,199, 69, 69, 89, 46,188, 93, 93, - 80, 91, 93, 12, 46,135, 0,143,195,108,250,153,182,254, 59,250,123,225,122,254,109,104,213,106,184,242,248,104,104, 80,226,119, -233, 57, 12, 18, 69,217, 69,254,116,253,189,240,246,231, 72,248,254, 59,200, 73,160, 99,112, 7, 92,189,246, 7,150, 78,238,239, - 80,253, 1,192,210,224, 65, 72,186,117, 18,144,105, 1, 65, 32,142,103, 92, 7,241,213, 34,122, 96, 98, 92,121,167, 86,231,167, -157, 61,158, 1,168,235,209, 64,212,163,134,211, 0, 25, 79, 3,141,174, 14,174, 74, 57, 4,165,183,177, 59,238, 22,186,132,133, -194, 90, 0,160, 57,220,220,220, 76, 73, 0, 2,129,192,226, 53,166,216,186,117, 43,182,110,221,218,162,206,236,229,229,245, 78, -110,110,174,135,183,183, 55,220,220,220,224,239,239,143,138,138, 10, 16, 4, 33,119,230,160, 65, 91,252,209,209,209, 20,160, 15, - 8,180, 39, 40,208,217,228, 63,100,200, 16,161,173,128, 90,166,177, 0, 30, 30, 30,177, 60, 30, 47,207,188,124,205,154, 53, 77, - 44,127, 0,232,220,185, 51,198,141, 27,183,195,150,253, 83, 92, 90,214, 36,218,255,227,255, 91, 2, 87, 30, 31,173, 91,183, 6, - 29, 19, 96,184,238, 97, 79,127,155, 39,236,135,197,171,191, 67,253,189,114, 4,121,183,194,181,235,133,152,179,102,167,221,253, -195,140,240, 9,179,207,155,202, 97, 61, 1, 79, 0, 46, 93,186,212,108, 50, 32,171, 30, 0, 0, 88,182,108, 89,218, 55,171, 9, - 17, 69, 77,145,118,105, 23, 0, 47,119, 87,244,234, 19,134, 94,189,251,131,199, 1, 26, 20, 58, 20,222,173, 70, 70,218, 97,145, -167,135,187,205, 47,104,148,203, 17,218,249, 46,148, 42,129, 33,107,139,190, 25,185, 9,148,160, 40,160,186,214, 21, 32, 0, 47, - 15, 45,250,134, 22,224,244, 5,219, 89,236, 76,173,127, 83,139,223,205, 39, 0, 46,148, 6,208,254, 51,222,233,120,182,159,209, -212,250, 55,181,248,233,178,220,107, 89,198,123,153,100,217, 51, 85, 2, 0,160, 77, 27,189, 50, 82, 93, 93, 13,111,111,111,163, -251,223, 30, 5,128, 86, 2,128,175,176, 48,122, 52,240,253,105,108,252,119, 20,102,188,247, 29,118,174,124, 11, 60,130, 0,223, -149,217,138, 29,218,250,191, 94, 88,142,144,142,129,216,190,109, 55,186,116,233, 2,159,118,193,232,223, 46, 24, 26,213, 63,238, -127, 23, 6, 50,105,235,255,139,185, 99,241,206, 39, 59,208,177, 27,209,162,250,163,173,255,241, 7,126,192,177,217, 49, 32, 58, - 12, 5,160,207, 10, 8, 0,183, 27, 27,141, 74, 98, 14,152, 37,240,217, 48, 39,143, 24,189,140, 18, 6, 79,171,151,118,233,222, - 7,117,110,192,109,220, 65,125, 65, 5, 42, 86,232,208, 80,211, 1, 55,207,230, 48,126, 33, 36, 73, 18,110,110,110,148, 66,161, -128,137,229, 73,185,185,185,129, 36, 73,226, 81, 12,150,245,245,245,223,188,245,214, 91, 83,182,110,221, 42,240,241,241,129, 84, - 42,197,218,181,107,235,212,106,245,243,206,252, 30,218,226,167,151,203,217, 27, 8,152,152,152, 72, 24,146,252,180,152,252, 1, -192,132,216,109,214,185,173, 12,131, 98,177, 88, 45,145, 72,134,238,221,187,247,114, 99, 99, 99, 91,141, 70,191,204,212,156,252, -123,245,234,133,161, 67,135, 78, 18,139,197,182,190,147, 39, 43,205,195,151,159,126,140, 95,147,142, 32,114,196, 64,156, 72,253, - 67,111,192,180, 11,134, 79,187, 96,132,231,231,227,249,233,175, 84, 22, 86,201,199, 3,216,199,212,250, 95,188, 37, 9,113,111, -140, 71,187, 54, 66,163,114, 97, 94, 15, 45,204,166,200,122, 2,158, 34,165,128,145, 2, 0, 0,239, 47,123, 47,237,155,111, 72, -209,237, 14,207,160, 91,247,158, 82,111, 15, 55,144, 20,160, 80,169,145,159,159,143,138,252, 75, 34, 47, 79, 15, 44, 92,184,208, -102,199,117, 19, 8,176,247,232,104, 17, 29, 1,223,172, 59,130,195,129,135, 7,115,235,137, 94, 2,232,225,223, 6,164, 78,163, - 39,127, 3, 52,132,139,205, 20,187,230,160,151,212, 68, 44, 89,223,132,180, 28, 33,127, 83, 37,192, 52,241, 79,117,117,181,237, - 23, 96, 67, 9,248,217,100,149,240,214, 21,111,254,115,162,105,128, 39, 67, 57, 29,253,189,176,247,194, 37, 92,189,249, 55, 6, -137,162,154,144,190, 61,228, 79,227,133,183, 63,199,254,129, 30,120,123,106, 15,167,212,223,210,224, 65,120,239,224, 94, 16, 95, -126,130, 35,173,135, 96,109,195,213, 38,215,167,249,248, 98,165,172,214, 46,226, 56,181, 58, 63,205,143, 23,129,226,154, 60, 84, - 84,221,197,189, 28, 79,112,117,222, 24,222,111, 36,118,159,221,253, 72, 7, 53, 39,101,251,187,240,227,143, 63, 70, 16, 4,113, -252,187,239,190, 19,188,248,226,139,117,114,185,124, 60, 28,152,243,111, 14,206, 88, 2, 40, 22,251, 57,133,252, 45, 88,169,182, -148, 15, 6,207, 38,174,148, 72, 36,193,245,245,245, 95,102,102,102, 46, 41, 41, 41, 65, 99, 99, 35,248,124, 62,218,182,109,139, -160,160,160, 23, 37, 18,201,239, 63,255,204,104, 75,128, 27, 0,194, 59,250,123,225,185,231,158,195,165, 91, 37, 8,236,218,187, - 73,127,123,126,250, 43,114, 0,235,190,140, 91,178,143,233,239,152, 39,236,135,136,212, 63, 49,251,147,255, 98,212,168, 81,104, -221,186,181, 69, 69,203,137,175,157,112,128,252,169,102,202, 89, 37,226, 17,144, 62,163, 84,192, 0,240,254,251,239,167,109,216, -176, 65,120, 49, 45, 71, 4,232, 35,105, 41,138,130,171,171, 43, 62,120,127, 25,227, 78,251,182,157,105,126,153,130,118,245,115, -181,114, 64, 43, 55, 70,192,211,196,111,239, 90, 44,218,213,159,123, 45, 11,185,215,178, 16, 20, 20,132,138,138, 10,135,136,223, - 39,168, 29,212, 12,130, 35,153, 98,246,231, 63,227,220,105,231, 85, 99, 65, 65,129,113,183, 63,141, 74,121, 31,249,219, 67,252, - 52,254, 53,208,195,105,245, 7, 0, 68,252, 7, 70,226,167,201,255,118, 99,163,104,154,143, 47, 82,128,180,149,178, 90,135,126, -251,111, 43,143,155, 12, 60, 10, 0,192,238,107,204, 19,246, 80, 20, 69,184,186,186, 26,189, 0,244,255, 0,224,234,234, 74, 88, -250,255, 33,227,204, 15, 63,252, 48,106,223,190,125, 75,235,234,234,226, 1,100, 56,251, 11,156,177,244,207,201,228,228,116,136, -197, 98, 5,128,165,134,163, 69,239,227,202,149, 43,195, 1,116, 13,236,218, 91,174, 81, 41,221, 13,253,173, 14,128, 12,192,141, - 78, 1,238, 47,137,197, 98,187, 26,116,196,199, 91, 31, 22,241, 59,164,104, 57,120, 63, 11, 39, 32, 44, 44,140, 17,249,219, 52, - 64, 91,186, 83,223,131, 0, 61,183, 79, 19, 63, 90, 72,252,244,220,180,172,188, 24,178,242, 98, 4, 5, 5,181,200,226, 7, 0, -173,142,180,219,251,208, 28,202,171,101, 14, 63,139, 57,232,185,125,103, 17,255, 3,168, 63, 2, 0, 34, 61, 60, 40, 83,171,127, - 0,207,165, 69,196,255, 63,134,191,234,234,234, 98,216,106,120,244, 56,117,234,148, 68, 34,145,252,183,176, 74, 46,215,168,148, -166,243,145,222,157, 2,220,253, 28,216,253,143, 0,244, 83, 25, 79,154, 82,197,226,225, 42, 1,140, 26,147,163,251, 8,179, 96, -193,130, 5, 11, 22, 44,158, 92,112,216, 42, 96,193,130, 5, 11, 22, 44, 88, 5,128, 5, 11, 22, 44, 88,176, 96,193, 42, 0, 44, - 88,176, 96,193,130, 5, 11, 86, 1, 96,193,130, 5, 11, 22, 44, 88, 60, 21,104,178, 10,224,210,165, 75, 14, 71,145, 90, 10, 38, -100,229,177,242,156, 37,207,176,183, 58, 7, 0,105, 41,249, 10, 91,127,214,229,133,133,133,209,117, 71,175,229,166, 46, 93,186, - 68,178,245,199,202, 99,229, 61,189,242,236, 86, 0,158, 18,180, 40,201, 68,116,116,180, 16,128,105,202, 80, 81, 98, 98, 98, 26, -171, 43, 62, 26,124,253,245,215,175, 94,185,114,165,255,249,243,231,223,115,117,117,133, 92, 46,255, 64, 34,145,172,102,144,129, -141,197, 63, 3, 11, 5, 64,199,214,196,227,141,168,168, 40,225,225,195,135,211, 28,252,172, 40, 57, 57,249,164,147, 18, 74, 33, - 42, 42,234,165,228,228,228,221,155, 55,111,246, 7, 80, 15, 64,199,246,185,167, 15, 79,213, 20,128,129,188, 91,244,249,189,123, -247,154,231, 11,151,182, 68,110,116,116,180,208,176,102,151,138,142,142,166,236,149, 69,217, 9, 75,235,131, 91, 40, 79,248, 40, -222,165, 68, 34, 33, 22, 45, 90,180,250,218,181,107,223,119,238,220,249, 61,129, 64, 0,149, 74, 5, 0, 95,239,223,191,159,156, - 58,117,170,232, 17,117, 25,202,254,227, 97,202,179,186, 7,187,233, 94,236, 14,237,207, 30, 29, 29, 45,164, 40,138,162,254,159, -101,217,244, 53, 91,109,208, 18, 10, 10, 10,168,130,130, 2,167, 17, 76,117,245,184, 38,251, 21, 56,155,168, 9,130,176, 75, 46, - 73, 82,148, 78, 71, 81, 36,105,249,136,138,138, 18, 38, 39, 39, 59,180, 11,213,150, 45, 91,198, 28, 57,114,228,228,232,209,163, - 65, 16, 4,181,107,215,174,113,246, 62,155,249,113,228,200,145,221, 47, 15,227, 67,188, 64, 92,157,231,153,191,111,254,252, 88, -146,190,102, 75, 94, 99, 99, 35,213,216,216,216,108, 59,164,239,121, 16,239,135,133, 85, 67,224,190, 4, 65, 60, 27, 29,222, 98, -222,108, 91,249,180, 31, 33, 90,180,141,219,222,189,123,165, 51,103,206, 4,160, 79,170, 97,210, 56,165,142,120, 21,104,133,130, -206,249,111, 72, 67, 42,141,142,142,182,207,171,144,232,111,199,183,218,238,251,141,147,223,100, 46,206,254,125,109,172,117,104, -198,245, 39,145, 72, 8,153, 76,182,167, 79,159, 62,211, 1,112, 40,138,130,155,155, 27,202,203,203, 81, 91, 91, 11, 31, 31, 31, -148,151,151,159,156, 58,117,170,232,192,129, 3,105,118,190, 19,138, 78, 7, 75, 16, 4,166, 79,159,142,113,227,198,137, 22, 44, - 88,192, 88,206,193,131,191, 25,255,159, 50,229, 69,155,231,182,160, 56,247,246, 63,213, 61,108,125,147,115,243, 50,183, 97,182, - 55, 85,162,183, 19, 54, 69,122,122, 58, 86,172, 88,113,223,187, 24, 57,114, 36,117,250,244,105, 70,109, 57, 49, 49, 81,138, 79, - 8,250,252,254,196, 51,159, 16, 45, 30,204, 31,227,177,165,137,165, 45,145, 72, 68,177,177,177, 24, 53,106, 20,117,230,204, 25, - 70,159, 61,103, 37, 39,227,129,196,247,144,156,156, 44,165, 55, 9, 27, 53,106, 20, 85, 87, 87,215, 28,225, 11, 99, 99, 99,141, -237,245,247,223,127,119, 39, 8, 2, 49, 49, 49,247, 0,180,158, 53,107,214,113,137, 68,194,177,199, 98, 95,125,124,181,241,255, -178,148,187, 32, 8, 2, 59,223,117, 7, 64,224,155, 87,190,126, 33, 48, 48, 16, 0,176,235,167,157,140,235, 42, 60, 60, 28,221, -186,117, 99,153,247, 49, 33,127,123, 61, 0, 84, 98, 98, 34,194,195,195, 41, 43, 3, 40,229, 64,231,118,170, 53,105, 46, 47, 49, - 49,209,116, 67, 12,187, 65, 16, 4,145,152,152, 72,208, 3,144,225,175,195,150, 38, 77,254,134,103, 34, 76,158,205,110, 69,133, -152, 89, 99, 60,152,148,219,130,231,161, 77,198,131, 73,185, 61,228, 79, 81, 20,232,221,217, 40,202,190,102, 34,145, 72, 56, 53, - 53, 53,255,245,241,241,153, 14,128, 51,119,238, 92,204,158, 61, 27,124, 62, 31,110,110,110, 16, 8, 4, 32, 8, 2, 92, 46, 23, - 50,153,140,113, 61, 70, 68, 68, 8, 1, 80,251,246,237, 3,253, 78, 40,138,194,254,253,251,177, 96,193, 2,169,225,250, 99, 7, - 75, 10,193,163,240,172, 37, 38, 38, 74, 1, 16, 47,221,156,137,153, 55, 44,246, 49,106,230,141,104, 17,241,153, 67,253,142,122, -255,253,247,209,181,107, 87,167, 60, 47, 65, 16,148, 88,236,135,128,128, 19, 78,173,135, 9, 19, 38,140, 77, 77, 77, 61, 73, 81, - 20, 17, 27, 27,155,102, 15,249, 91,195,129,196,247, 16, 31, 31, 15,146, 36,241,222,123,239, 49, 82, 40, 76,201, 31, 0,142, 28, - 57,146, 52,106,212, 40, 0,240,139,137,137,209,142, 30, 61, 26, 98,177,152, 52,196,205, 48,241, 50, 54, 57, 95,187,118, 45, 94, -122, 78,111, 27,238,124,215, 13, 47, 15,227,227,131,200,247, 25,255, 38, 15, 15, 15,140, 26, 53, 10,153,153,153,198,241,212,252, -160,239, 97,179, 23, 62, 58,242,111, 86, 1,160,201, 42, 51, 51,211,152,118,210,212,122,178,151,104, 77, 6, 17,103, 15, 74,230, -202,128, 83, 93,195, 22,166, 4,236,134,169, 66, 97,176,254,159,198,118, 70,153, 14, 38, 37, 37, 37,198, 11,197,197,197,140, 21, - 70,153, 76,246,149, 92, 46,127,133,195,225,112,102,205,154, 5,153, 76,134,210,210, 82,184,184,184,128,199,227,129,199,227,193, -197,197, 5,110,110,110, 80, 40, 20, 96,226, 66,220,188,121,179,240,248,241,227, 82,130, 32, 48, 99,198, 12, 80, 20, 69, 43,121, -196,140, 25, 51, 0, 0,169,169,169, 82,118,168,104,158,252, 13,239, 87,100,170, 36,211,239,222,212,171,229,200,160,158,152,152, - 72, 24,222, 11, 54,111,222,236, 20,101,236,163,143, 62,162,141,130, 22,123, 38, 34, 35, 35, 35, 46, 92,184,144,218,165, 75, 23, -132,132,132, 80,195,135, 15, 55,122, 78, 12,187, 63, 58, 68,254,107,214,172, 1, 65, 16,224,112, 56,184,112,225, 2,152,120, 99, -204, 60, 18, 47, 16, 4,129,151, 95,126, 89,107, 40, 82,199,196,196,212, 9,133, 66, 44, 88,176,128,156, 56,113,162,205,223,110, -186, 43,105, 89,202, 93,128, 0, 18,222,249, 39,107,241,206,119,221, 17, 51,220, 21,203,159,255,128,241,115, 49,177,252, 89,239, -192,195, 35,255,216,229, 43, 45, 94,231, 53,215, 33,195,195,195,169,204,204, 76,208,158, 0,154,184,194,195,195,237,234,228, 15, -154,252, 77,173,234,199, 61, 96,207,116, 74,224,169,211, 0, 40, 10, 37, 37, 37, 40, 43, 43, 51,150,153,159,219,176,254,185, 71, -143, 30,157, 24, 26, 26, 10, 46,151,139,220,220, 92, 80, 20,133,191,255,254, 27,106,181, 26, 4, 65,128,199,227,129, 32, 8,232, -116, 58,200,229,114, 28, 56,112,192,166,220, 19, 39, 78, 72, 1, 96,198,140, 25,247,181, 91,122,170,135, 38, 10, 38,237,218,220, -173,111,235,156,137,149, 79,195,218,116, 0, 19,215,191, 57,210,211,211, 97,176, 12, 91,166, 0,127, 66,128,248, 76,175,192,153, - 42,175, 20, 69, 1,159, 16,152,121, 35,218,225, 64, 89,130, 32, 40,195,123, 49,146,145,225,125, 17, 45,145,215,189,123,247,251, -200,205, 81,184,186,186, 82,215,174, 93, 67, 69, 69, 5, 81, 81, 81,129,176,176, 48,170,160,160, 0, 92, 46, 23, 90,173,214,161, - 47, 24, 61,156, 75, 43, 15, 88,182,108, 25,214,174, 93,139,211,167, 79,131, 32, 8, 76,158, 50, 31,119, 10,152,109,224,120,228, -200,145,223, 12,239, 88, 9,128, 52, 28,136,137,137,169, 5,224,155,156,156,140,168,168, 40,161,169, 66,222, 28,244,214,255,253, -251,152,232,167, 3,128, 93, 59,179,236,146,199,226,241, 37,255,102, 61, 0, 6,235,159, 48,245, 4,208,150,127,102,102,102, 75, -200,223, 86,128,146, 67,242, 76, 60, 19, 66, 56, 16,224,244, 0, 44, 39,202,100,240, 49, 62, 15, 93,230,172,224, 23,106,175,159, -241,112, 6, 26, 38, 45, 52, 30,118, 88,254, 20, 61,216,118,232,208, 1,131, 6, 13,194,160, 65,131, 0,192,120,110,126,175, 21, -248,250,251,251,247, 81,169, 84,168,174,174,198,185,115,231,144,145,145,129,138,138, 10, 40, 20, 10,208,115,164, 20, 69, 65,163, -209, 64,165, 82, 49,154, 98,160,219,134, 53,114, 79, 76, 76, 36, 8,130, 0, 83,207,204,193,131,191, 25, 15, 38,231,182,160, 56, -247,118, 19,162,167, 15,211,115,211,123,152, 98,212,168, 81, 72, 79, 79,111, 89,131, 48,153,243,135,126, 26, 75,100, 32,103,130, -190,134, 22,198,222,152,190, 23,218, 11,224, 44, 56,195, 11,208,190,125,123, 20, 23, 23, 19,230,202,174,163,228,127, 32,241, 61, - 99, 27,166, 49, 98,196, 8, 0,192,169,179,204, 23,107, 68, 69, 69, 69, 26,230,254,175, 3,144, 27,198,115,250, 48,106,221, 76, -131, 11,155,206,253, 91, 80,174,236,148,199,226,241, 7,143, 73,231,164, 61, 1,246, 90,254,203,151, 47,167, 86,173, 90,229,180, -135,181, 37,207, 48, 72, 57,173,113, 50,157, 67,107,142,116, 76,100, 53,136,197, 98, 79,107,215, 29,133,233,220,191, 51,148, 0, -211,185,127,166, 74,192,236,217,179,225,225,225, 1, 79, 79, 79,120,121,121,193,199,199,135,244,243,243,227, 36, 39, 39,227,213, - 87, 95, 53,222, 39, 16, 8, 48,126,252,120, 52,163, 4, 4,168,213,106, 84, 87, 87, 67,169, 84,194,199,199, 7,174,174,174,208, -106,181,160, 40, 10, 58,157, 14,106,181, 26, 26,141, 6, 58,157,206,174,248, 2, 67,208,154,213,235,166, 86,232,163,132,173,128, - 64,123,209, 82, 37,128,248,204,250,116,223,204, 27,209, 6,114,117, 80,182,153,245,111, 82,142, 25, 51,102,216, 29, 12,104,110, -253,155,202,115, 20,225,225,225,148, 78,167, 67, 88, 88, 24,117,233,210, 37, 34, 44, 44,140,210,104, 52,144,201,100, 14,203,164, -141, 41, 30,143,135, 37, 75,150,224,194,133, 11,248,103,222,159,121,155, 62,122,244,232,209,145, 35, 71, 2,128,151,129,244,229, - 0,176,123,247,238, 86,167, 78,157,242, 54,244, 15,194,240,215,166,224,181,223,173,197,203, 67,239,183,254,103,127, 47,199,238, -115, 26, 80, 20,133, 1,179, 6, 32,107,103, 22,241, 40,141, 43, 22,206,177,254,109,122, 0,104, 75,149,110,176,166,241, 0, 76, -176,106,213, 42,218, 98,112, 10, 24,200,115,120,126,221,176, 68,175,201,145,154,154, 74,210,171, 2, 90,106,177,199,198,198,122, - 62,205, 13,110,203,150, 45, 88,179,102, 77,147,118, 69,147,255,148, 41, 83, 48,101,202, 20,189,133,115,234, 84,115, 98,252,243, -243,243,149, 58,157, 14, 53, 53, 53,168,172,172, 68, 77, 77, 13,228,114, 57,228,114, 57, 26, 26, 26, 80, 87, 87, 7,153, 76, 6, -133, 66, 1,149, 74, 5,157,206,182,197, 68, 16, 4,246,237,219,103,151,194,246, 36, 35, 61, 61,189,201, 97,138, 37, 75,150, 8, - 77,207,153,204, 57, 91,152,243,111, 98,185,183, 36,144,203,210,103, 41,138, 34,246,237,219,231,212, 88,128,125,251,246,217,221, -135, 7, 14, 28, 72,233,116, 58, 99,130,150,176,176, 48,138, 36, 73,220,187,119, 15,141,141,141, 14,253,230,127, 47, 31,141, 83, -167, 78,129,220,227, 11,138,162, 16, 31, 31,111,124, 71,233,231, 72, 48,157,249,136,138,138,122, 17, 0, 98, 98, 98, 74, 12, 10, -128,106,215,174,132, 86, 11, 23, 46,108,117,234,212, 41, 76,152, 48, 33,194,158,156, 0,101, 41,119, 65,128, 64,130,137,245, 63, -235, 59, 57,184, 47,203,176,235,156, 26,139, 23, 47,198,170,163, 95,179,204,250, 20,145,191, 77, 15,128,249,188,191,105, 60, 0, -211,105,128,196,196,196, 52, 67,128,144,212,204,147,228,232,128,113,159, 60,122, 90,192, 48, 15,233,148, 9,246,113,227,198, 93, - 77, 77, 77,237,243, 56,190, 96,218,234,119,150,219,159,182,250,237,112,251, 55, 65, 66, 66,130,241,255,255,252,231, 63,248,241, -199, 31, 1, 64, 13,128, 79, 19, 63, 0,140, 31, 63,222,150, 2,160, 8, 13, 13,133, 92, 46,135, 90,173, 70, 69, 69, 5, 92, 93, - 93,193,227,241,140, 30,128,198,198, 70,200,229,114,168, 84, 42,200,100, 50, 76,159, 62, 93,180,127,255,254,102,159,143,182, 50, -109, 44,107,197,140, 25, 51,108, 42, 10,122,133,230,193,197, 0, 56,114,221, 28, 38,203,253,238, 67,124,124,188,116,201,146, 37, -162,248,248,248,180, 71,218,134,173, 88,255,166,176, 39, 22,192,154,245,239, 40, 6, 14, 28, 72, 93,188,120,145, 8, 11, 11,251, -148,110,218, 58,157,238, 19, 15, 15, 15, 84, 86, 86, 58, 52,198,124,252,225,104,164,165,165,129,216, 23, 0, 0, 56,246,177, 23, -198,127, 81,143, 81,163, 70,225,203, 85,167, 64, 81, 20, 99,111,197,145, 35, 71, 14,140, 30, 61, 26, 0, 42,118,239,222,217,254, -212,169,211,190, 20, 65, 97,226,132,137, 83, 14, 31, 62,156,116,248,240, 97, 70,114,104, 47,231,218,181,107,241,242, 48,151,166, - 22, 63, 40, 44, 89,188, 4,173,199,183,193,211, 26,183,244, 84, 27,101,171, 62,180,170, 32,132,133,133, 53,175, 0,152, 70,252, - 27,200,223, 24, 44, 69,123, 2,152,106,254, 22, 72,187, 69,176, 32,207,233,115, 82,177,177,177,125, 82, 83, 83,157, 57,224, 61, -173,237,140,128, 62, 10,220,104, 73,191,254,250,235, 0,192, 55,105, 75,198,107,134, 65,203, 26,174, 13, 29, 58,244,213,180,180, -180, 68,157, 78,135,186,186, 58,104, 52, 26,227,188,191, 82,169, 52, 46, 49,164, 3, 3,247,239,223,159,198,160,189, 16, 48, 44, - 1, 52,111,183,209,209,209, 20, 77,250,227,198,141, 19, 49, 81, 0, 30, 84, 30, 0,211,185,127, 83,242, 55,159, 22, 96,240, 62, -154, 3, 21, 31, 31, 47,125,233,165,151,176,103,207, 30, 71,189,101, 66, 83,207, 9,125, 78, 7, 12,206,188, 17, 77,221,186,117, -203,234,231,233,132, 63, 71,143, 30,181,234,177,187,125,251, 54, 99,207, 76,117,245, 56, 10, 0, 34, 34,242,145,159,159,111, 49, -186,188,170,106, 44,128, 26, 0,182,199,173, 94,189,122, 81, 23, 47, 94, 36, 12,131,229,167, 0,192,225,112, 62,185,115,231, 14, -106,106,106, 28,234,200, 28, 14,161, 87,216,105,242,191,172,197,143, 82, 53, 0,224,203, 85,167,236, 30, 35,232, 62,177,112,225, -194, 48,138,162, 16, 53, 41,106,250,161,164, 67,191, 50, 37,126, 83, 81, 47, 78,125,225, 58, 65, 16,189, 40, 10,224,190, 44, 3, - 69, 81, 88,178,116, 9,218,140,111,219,194,188,170,250,101,189,116,187, 99, 51, 9, 62,126,104,110, 21,128,113,240, 54, 91,198, - 70, 37, 38, 38,218,237, 50, 53, 33,109,167, 60,184,169, 60,122,253,255, 83,186,188,238,137,128, 89,221, 55, 89, 34,102,229,218, -125,131,129, 88, 44,214, 74, 36,146,253,163, 71,143, 94,148,156,156,188, 78,171,213,162,182,182,214, 24, 3, 0, 0, 21, 21, 21, -168,173,173, 5, 69, 81,176,167, 61, 69, 68, 68,136,142, 31, 63, 46, 77, 76, 76,108, 98,125,210,159,143,136,136,176, 43, 25,208, -131,128,226,220,219,142, 16,254,125, 4,111, 99,200, 38, 8,130,160, 28, 33,127,131,167, 45,205, 82, 95, 4, 0,147,160, 64, 70, - 88,176, 96,129,148,193,119, 50, 54, 52, 76,167, 42,239, 39, 34,102,201,241,186,118,237, 74, 93,191,126,157,118,249,127, 10,224, - 19,149, 74,133,188,188, 60,200,100, 50, 71,169,144, 34,247,248,225,216,101,253, 74,189, 29, 82, 53,118,159, 83,131,162, 40,156, - 62,239, 56, 39,166,167,167, 99,194,132, 9,162,195,135, 15,167, 29, 74, 58,228,168, 24, 14, 73,146, 46, 0,176,231,188, 6,139, - 23, 47, 70,155,200,182,204,213, 73, 11,104,108,108, 4, 0,228,231,231, 83, 91,182,108, 49, 42,100,166,177, 36, 59,118,236, 48, - 29, 31, 88,247,130, 19, 65, 91,247,150, 44,127,243,235,205, 77, 1, 16,134, 41,128,251,150, 77,217, 51, 5, 96,113,160,112, 30, -233,152,202,115,234,250,127,122,238,223, 81,216, 82, 72,236, 85, 88,172,185,251, 29,157, 6,176,230,238,119,112, 26,192, 52, 40, -136,176,227, 26, 44, 40, 1, 20,128,245, 18,137,100,115, 66, 66,130,134,207,231, 67,165, 82, 65,171,213,130, 36, 73,248,250,250, -162,166,166, 6,246,102, 83, 60,126,252,120, 26,244,235,254,169,125,251,246,193,160, 8, 24,151, 6, 30, 63,126,252,127, 98,112, -120,233,165,151,168,198,198, 70, 28, 58,116,200,222,246, 44,180, 81,223,212,204, 27,209, 34, 38,222,184,247,223,127,255, 62,227, -194, 28, 31,124,240, 1,197, 52,200, 83, 44,246,179, 41, 79, 44,246, 99, 36,204,205,205,141, 30, 36, 41,138,162, 32,151,203, 81, - 90, 90,234,240,156,191, 41, 34,191,168,111,114,222, 18,242,215,233,116, 4, 0, 56, 96,241,155,131, 60,248,123, 82,119,211, 76, -128,206, 66,115, 10,153,137, 2,192,226,113,244, 0, 24, 94, 28, 97, 79,249, 35,182, 64,211, 30,179,231, 33,236,176,152,109, 40, - 34,227,156,246, 92, 51,103,206, 20, 57,144,222,183, 89, 11,205,130, 5,218,156,117,202, 40,104, 76, 44, 22,107, 1, 16,211,167, - 79, 23, 22, 22, 22, 74, 21, 10, 5,116, 58, 29,122,245,234, 37, 26, 52,104,144,195,239,123,223,190,125,166, 75,206, 28,242, 26, - 61,232, 24, 0, 91,231, 76,244, 69, 67,116,120, 83,194, 57,125,218,110,183,191, 97,173, 63, 53,243,198,253, 10, 28, 69, 81, 20, -157, 35,192, 68, 33, 51, 6,204, 57,218, 55, 0, 96,239,222,189,132,179,250, 26,211,123, 0,160,186,186, 26, 93,187,118,165,234, -234,234,208,185,115,103,100,103,103, 59,101,172,227,188, 84, 3,130, 32, 48,229,133, 88,218, 13,131,213,171, 22, 24,255,183, 55, - 99,166,179, 32, 22,139,201,205,167, 54, 59, 85,230,156, 57,115, 12, 94, 23,137, 39, 0,173,225,160,196, 98, 49,105,114, 15, 59, - 29,240,184, 43, 0, 79, 16, 90,220, 73, 31, 87, 55,148,179,159,235, 1,120, 97, 30,104,189, 25,230,248,141,223,113,227,198,141, - 71,252, 70, 72,226,241,150,167,175, 43,123, 51,202, 89,197, 39, 77,246,177,160, 44, 93, 51, 88,222,105, 79,195, 64, 82, 86, 86, -102,124, 31,249,249,249, 78,123, 39, 18,201,102, 74, 44, 94, 64,252,254,155,132,209, 7, 28,221,222,213, 17, 24,150,245, 57,125, - 76,104, 78,185,102,221,254, 15, 31,150,166, 6,136,135,217,208, 88,176, 96,193,130, 5, 11, 22,143, 7, 56,108, 21,176, 96,193, -130, 5, 11, 22,172, 2,192,130, 5, 11, 22, 44, 88,176, 96, 21, 0, 22, 44, 88,176, 96,193,130, 5,171, 0,176, 96,193,130, 5, - 11, 22, 44,158, 10, 52, 89, 5, 64,231,188,118, 4,150,130, 9, 89,121,172, 60, 86,222,195,147, 23, 23, 23,215, 84,187,231,112, -140,217,229, 76,151,154,209,217, 20, 77,151,158, 89, 74, 31,236,233,233, 9,129, 64, 96,252, 60,135,195, 1,151,203,189, 79, 30, -189, 49, 19, 73,234, 87,121, 89,219, 44,135,125,191,214, 33,145,108, 17,114,121,174,160, 72, 45,230,207,127, 35,205, 17,121,155, - 55,111, 22,101,103,103,243,194,194,194, 82,205,179,238, 57, 40, 79,152,157,157,141, 77,155, 54,165,177,253,237,201,147,103,183, - 2,240,191,136,192,192, 55,154, 84, 92,101,229,118,226,177,146,247, 70, 32, 5, 0,149,219, 43, 9,211,255, 91, 32,178,133,201, - 61, 31,184,188,255, 89,108, 93,183, 70, 88,113,245, 28, 70,249, 85, 72,219,107,139,144, 67,117,197,133, 70,127,145,119,232, 16, - 44, 90,186, 44,205,214,231,207,156, 57,131, 17, 35, 70, 24,137,159, 38,108,130, 32,238, 35,108,146, 36,141,199,157, 59,119, 44, -202,187,120,241, 34,194,195,195,225,230,230, 6, 30,143, 7, 46,151,219, 68, 38, 77,250, 58,157,206,120,168, 84, 42,100,102,102, - 34, 36, 36,228,169,123, 63, 18,137,132, 16,139,197,212,230,205,155,133,127,255,253, 55,110,221,186, 37,245,245,245,197, 47,191, -252,210,162,246,191,101,203, 86,161,171,192, 31,190,126,207, 72, 27, 27, 74, 68, 91,182,108, 19,110,220,104, 95,238,135, 77,155, - 54, 9, 19, 19, 19, 79,230,228,228,224,208,161, 67, 8, 13, 13,197,123,239,189,199, 53, 93,123,239,128, 60,105,126, 94, 46, 66, -130,187,129,239,234,138,197,139,151,140,137,141,141,101,183, 2,126, 90, 61, 0, 79, 18, 34, 34, 34,108,106, 60,199,143, 31,183, -217, 49,105,130, 54, 39,110, 71,225,108,121, 15, 0,132,157,164,109, 51,181,172,147,229, 49,249,188,249,247, 63,217,196,178,121, -179,240,250,153, 99, 40,220,253,141, 84, 46, 87, 65, 51,132, 3,183, 14, 4,186, 23, 94,198,179, 94,148,180,166,226, 47,180,219, -252,255, 68,211, 23,124,214,172, 18,112,253,250,117,112,185, 92,140, 28, 57, 18, 60, 30,207,120,208, 10, 1,109,245,107,181, 90, -232,116, 58,104, 52, 26,220,185,115, 7, 39, 79,158,180, 40, 79, 46,151, 35, 43, 43, 11, 67,135, 14, 5,159,207,135,139,139, 75, - 19,153, 36, 73, 66,171,213, 66,171,213, 66,163,209, 64,161, 80, 32, 43, 43, 11, 13, 13, 13,143, 3, 89,115, 12,109,131, 3, 64, -219,146, 60,244, 18,137,132,136,139,139, 35,227,226,226, 16, 16, 16,128,127,255,251,223,152, 49, 99, 6,234,235,235, 17, 16, 16, -224, 80, 6,210,128,128, 0,227,243,124,244,209,135,248,121,103, 38,220,220, 90,129,203,229, 75, 27,234,139,236,150,153,145,145, -129,134,134, 6, 12, 29, 58,244,206,184,113,227,218, 86, 85, 85,225,216,177, 99,186,249,243,231, 99,235,214,173,205,246, 17, 85, - 65,238,125,117,115,229,230, 77,164,121,185, 99,105,252,103, 69, 3, 6,246,233,120,183,184, 28,199,146,211, 78,238,218,181,123, - 92, 76,204,203, 39, 88,234,124,252, 65,167,254, 53,243, 20, 48, 82, 0,204, 83,183,218, 58,127,232,228,255,230,155,111, 54,123, - 79, 77, 77, 13, 0, 80, 76,148, 0,154,172, 91,106,173, 63, 8,121,166,150,191, 19,172,127,123, 73,155, 41, 89, 59, 91,158,233, -189,166,127, 1, 0,213,213,250,204,136,254,254,169, 79, 69, 71, 45,248, 51, 21, 33, 69, 82,105,145,156,196,180, 16, 46,158, 9, -210,130,244,167,224,226,207, 69,125, 21, 31,110,245, 10,244,204, 94, 47,253, 57, 62, 78,244,234,146, 21, 86,149, 0,130, 32,112, -227,198, 13,240,249,124,140, 25, 51,198, 72,218, 46, 46, 46,224,112, 56,160, 40, 10, 26,141, 6, 90,173, 22, 42,149, 10, 69, 69, - 69,144, 74,165, 86,183, 84,230,112, 56,208,104, 52,200,206,206,198,200,145, 35,225,230,230, 6, 87, 87, 87,163, 60, 90, 1, 80, -169, 84,104,104,104,192,149, 43, 87,160, 84, 42,141,211, 4, 76, 16, 19, 19, 35,228,114,185,210,250,250,122,240,249,124,148,151, -151,191, 61,109,218,180,122,129, 64,240,179, 35,164, 29, 19, 19, 51,147,203,229,238, 73, 78, 78,166,229,229, 76,155, 54,237,111, -137, 68, 50, 67, 44, 22,171, 29,177,132,227,226,226,164, 43, 86,172, 40, 7,208, 10,208, 79,181, 92,191,126, 29,173, 90,181, 66, - 88, 88, 24,126,250,233, 39,187,201,255,135,185,115, 49,113,192, 0, 0, 64,155, 69,139,224,230,222, 26, 13,117,133,168,147,229, -137, 98, 99,231,165, 89,203,231,110, 13,253,250,245, 67,121,121, 57,206,156, 57,211,153,195,225,224,202,149, 43,240,247,247, 71, -122,122, 58, 94,123,237, 53, 42, 59, 59,187,217,207, 87,125,181,180,201,185,167, 90,131,118, 90, 37, 22,191,255, 73,199,248,213, -255,193, 55,171, 55,162, 61, 71,135,141,171,215,164,190,246,218,107,176, 37,143,197,227, 71,254,116, 57,211,189, 0,238,203,255, -109,235,252, 97,194,153, 59,245, 61, 9, 48, 85, 2, 30,146, 39,192, 94, 75,157,176, 97,157, 59, 34,207,210,223,167, 42,113,213, -119,171,190, 20,134,102,255, 32, 45,231,234, 16,226, 3,116,238, 68,129,219,143, 15, 94,183,110,224,171,148, 80,157, 45,130, 74, -198, 3,151,116,129, 50,245,103,233,214, 13,171, 69,243,223,178, 60, 29, 64,187,231,115,115,115,225,231,231, 7,145, 72, 4,129, - 64, 0, 62,159, 15, 30,143,103,180,250,149, 74, 37, 74, 75, 75,113,234,212, 41,112, 56, 28,112, 56, 28, 52, 39, 79,167,211,225, -218,181,107, 24, 49, 98, 4,188,189,189, 33, 16, 8,192,229,114,161,213,106,161, 86,171, 81, 87, 87,135,191,254,250, 11, 42,149, - 10, 60, 30,207, 24, 11, 96, 11, 35, 71,142, 20,222,188,121, 83,122,251,246,109,212,213,213,129,207,231,163, 77,155, 54,235, 79, -159, 62,141, 97,195,134,241, 36, 18,201,143,246, 40, 1, 35, 71,142,156,122,243,230,205, 61,102,242, 66, 79,159, 62, 29, 58,108, -216,176, 93, 6, 37,128,145,188, 77,155, 54, 9,213,106, 53,202,202,202,104,151,183,177,146, 86,172, 88, 81, 18, 23, 23,215,126, -198,140, 25, 99,222,125,247, 93,187,198,191,173,219,126, 20,126,184,124, 89,147,178,178,117,235,208,230,197, 14,248,230,155,239, - 68,115,231,190,226,208,120,122,230,204, 25,233,159,127,254,137, 15, 63,252,176,142,203,229,122, 11, 4, 2, 12, 27, 54, 12, 82, -169, 20,201,201,201,104,223,190,189, 29, 61,143,192, 47,185,119,177,255, 86, 9, 14,254,254, 19,184, 92, 2, 75, 23,189, 74,246, -111, 19,200,217,178,248, 19,108,181, 87, 30,139, 71, 66,254,230, 74,164, 37,165,192,225, 85, 0,143,122,123,219,110,221,186,137, -108, 29, 15,219, 90,127, 16,242,156,104,245, 51, 37,109, 71,200, 26,166,214, 57,109,161, 27,228, 80, 14,202,179, 58, 80,251,251, -167, 58,100,253,111,216,176, 65, 56,111,222, 60,202, 90,153,249, 53,107, 48,189,127,195,134, 13, 66,243,107,230,101,205,214,215, -181,139,210,210,146, 58,180,242,226,161,155, 23, 5, 94, 32, 9,222,115,207,195,163,255,207,112, 27,248, 45, 92,125,220,192,111, - 80, 64, 46,215,161, 19, 87,142,244, 4,235,169,100, 57, 28, 14,120, 60, 30, 92, 92, 92,112,235,214, 45, 92,185,114, 5,222,222, -222, 8, 8, 8, 64, 64, 64, 0, 2, 3, 3,225,235,235, 11,153, 76,134,244,244,116,112,185, 92,227,220,190, 37,208,215,249,124, - 62,116, 58, 29,114,114,114,224,238,238,142,192,192, 64,180,106,213, 10, 65, 65, 65,240,244,244, 68, 78, 78, 14, 52, 26,141,113, -138,192,154, 66, 97,110,249,223,187,119, 79,154,151,151,135,174, 93,187, 34, 50, 50, 18,131, 7, 15,134, 92, 46,199,201,147, 39, -145,157,157,189, 93,169, 84,190, 98,135,229, 47,186, 87, 94,241,107,254, 93, 25,188, 66,134, 34, 52,242, 13,180, 31, 60, 5, 53, - 42, 14,142,167,158, 64,118,118,246, 52,165, 82, 57,159, 41,249,215,213,213,225,242,229,203,210, 51,103,206,160, 95,191,126,136, -139,139, 11, 4, 64, 26, 60, 0,237, 1, 64, 32, 16, 48, 38,235,173,219,126, 20,254,146,144, 36,244, 15,232, 35, 77,216,125, 25, -115,127,248, 1,201, 89, 89, 72,206,202, 66,155, 69,139, 0, 0, 26, 77,227, 41, 71,250,220, 11, 47,188, 64, 29, 60,120, 16,211, -167, 79,191,227,229,229,197,113,119,119,207,204,200,200,192,153, 51,103, 80, 89, 89,137,208,208, 80,251,148,210,172, 91, 88,253, -199, 85,108, 93,253,209,101, 30, 87, 1,142,174, 30, 95,175,253,129,179, 39, 61, 19,165, 28, 30,158,121,230, 25,150,101,159, 18, -240, 28, 37,248, 71,181,121,197, 3,179,176,255,183, 21,129, 7, 50,175,222, 66, 87, 61, 97,163,220, 46,165, 98,245,234,213,194, - 19, 39, 78, 72,115,115,115,173,150,101,100,100, 48,146, 69,223,151,145,145,129,234,234,106,233,234,213,171, 69,203,150,233,173, -114, 75,101,205,193, 91, 89,133,228, 66, 37,218,215,112, 49,192,155, 64, 80, 5, 16,194,243, 1,135, 8, 0,165,188,135,198,123, - 4,174, 21,146, 40,107, 84,130,199,225,160,175,191,171,212,218,239, 54, 85, 0, 92, 93, 93,145,151,151,135,246,237,219, 35, 34, - 34, 2, 92, 46, 23, 36, 73,162,170,170, 10,103,206,156,129,139,139, 11,248,124, 62,212,106,181, 85, 5,128,246, 14,208, 74, 0, - 69, 81,200,207,207, 71, 72, 72, 8,124,124,124,208,208,208,128,172,172, 44,232,116, 58,184,186,186, 66,165, 82, 65,165, 82, 89, - 29, 59,232, 32, 58, 0,168,168,168,144, 22, 23, 23,163,127,255,254, 16, 10,133,232,208,161,131,168,177,177, 17, 65, 65, 65,210, -212,212, 84,156, 63,127, 30,190,190,190, 67, 37, 18,201, 78,177, 88,172,179, 85,143, 21, 21, 21, 39,239, 85,203,224, 31, 58, 20, -221, 70,190, 4,223, 14,161, 80, 53,214,162,240,207,195,184,117,226, 39, 90, 30,163,247,107,136,125,144,150,150,150,162,117,235, -214, 16, 8, 4,162,203,151, 47, 75,227,226,226, 56, 6, 15, 0, 0,220,140,139,139, 35,153,180,193,109,219,127, 18,250,250, 61, - 35,245,245,127, 6, 28,142, 11, 52,154, 70,108,255, 81,138,185,175,139,104,143, 2,230,207,159,143,160,160, 32,210,222,190,247, -234,171,175, 82, 9, 9, 9, 24, 57,114, 36, 6, 14, 28,216, 25,128,246,196,137, 19,225, 5, 5, 5,112,115,115,131,155,155, 27, -162,162,162,198,236,221,187,247, 36, 19,121, 59,255, 46,194,183,127,221,196,182,149,203,171, 59, 60,211,185, 95, 99, 67, 13,126, - 63,242, 23, 46, 95,249, 27,190, 20, 9,126,217, 61, 68,189, 61,123,220,158, 61,123,255,183, 92,176, 79, 16, 44, 77, 31, 89,243, - 10, 88, 83,213,137, 25, 51,102,152, 90,208, 68,116,116,116,115,231, 79, 44, 42, 43,183, 19,166,199,227, 38, 15,120, 32,238,255, -230,172,246, 22, 61,179,163,214,185, 61, 30, 0,123, 17, 19, 19, 35, 76, 74, 74,106, 66,254,150,202, 28, 65,110,110, 46,146,146, -146,164, 49, 49, 49,194,230,202,172, 18, 87,101, 17,206,221, 85, 64,174, 35,113,186,136, 68,153,150, 7,157, 42, 19, 53,215,223, -196, 79,139, 98,113,232,152, 12, 87,170, 40, 92,170,208,226, 90,149, 22, 85,165,101,205,122,229, 76,149, 0,129, 64,128, 59,119, -238,224,230,205,155, 0,244,113, 49,127,100,194, 62, 90, 0, 0, 32, 0, 73, 68, 65, 84,252,241, 71,147,185,252,230,230,235, 9, -130, 48,122, 1,104,121, 20, 69,161,168,168, 8,157, 58,117, 66,105,105, 41, 72,146,132, 64, 32, 48,202,106,110, 74,193, 20,133, -133,133, 80, 42,149, 8, 15, 15, 71,135, 14, 29, 68, 92, 46, 23,222,222,222, 24, 50,100,136,200,211,211, 19,133,133,133,168,171, -171,187,194,180, 29, 20, 22, 22,130,228,240,209, 62,108, 28,124, 59,132,130,195,117,129,155,119, 16, 58, 13,137, 2,223,195,143, -150, 87, 96, 75,206,230,205,155,133,181,181,181,210,146,146, 18,116,236,216, 17, 34,145, 72,244,243,207, 63,167, 85, 85, 85, 17, - 0, 48,116,232, 80,173,225,214, 80, 31, 31, 31, 72, 36, 18,155, 1, 15, 2, 65, 0, 2,130,250, 67,167, 85,161,252,110, 6,202, - 74,206,140,173,172,200,250,200, 32, 15, 0,112,175,172, 12, 6,121, 46, 76,219,158, 88, 44,158,145,144,144,128,217,179,103, 99, -214,172, 89, 0, 64, 30, 59,118,140,151,148,148,132,185,115,231,142,191,120,241, 34,113,246,236, 89, 34, 46, 46,142, 81,228,126, - 78,157, 28,203, 79, 93,194, 87,239,197, 98,228,164,113,254, 58, 74,139,189,191,158,194,247,235,127,198,145, 37,175, 97,107,255, - 78,232,228,195,195, 71, 31,197,177, 65,128, 79, 8, 46, 93,186,100,149,252,155,245, 0,152,207,237,219, 58,127, 26,241, 0,150, -224, 57,132, 47,158,253, 66,180, 96,193,130, 39,161,190,155, 76, 41, 60,224, 32, 61, 70,239, 33, 42, 42, 74,120,235,214, 45,169, - 90,173,110,182,172, 37,168,169,169, 65, 99, 99,163, 52, 42, 42, 74, 84, 84, 84,116, 95,217,225,195,135,173,190,187,236,106, 5, -100,106, 18,217, 21, 90,148,214,106,209,250, 15, 30,250,237,205,197,157,130,107,248,251, 79, 53,180, 60, 46,212, 36,160, 84, 83, -168,161, 72, 4, 53,179,173, 61,189,220,143,158,187,167, 35,246,239,221,187,135,206,157, 59,163,160,160,192,232,242,231,241,120, -198,251,237,157,206, 51,205, 33, 64,255,125, 64, 83,130,181,112,110,204,135, 77,178, 38, 73, 18,141,141,141,250,193,145,199, 19, -189,249,230,155, 77,222, 93,125,125, 61,239,224,193,131,152, 50,101, 10,103,249,242,229,247, 86,173, 90,165,181,213, 22, 9, 66, -175, 16, 41,228,247,208, 80, 95, 36,154, 55,239,181, 52,137, 68,146, 14,224,171,250,250,122, 28, 60,120,208,168, 56,134,132,132, -168,153,180,237,149, 43, 87, 78,249,230,155,111, 18,163,162,162, 48, 98,196, 8, 0, 32,207,158, 61,203,249,237,183,223, 32, 20, - 10, 39,109,216,176,225,184, 61, 21,115, 87,174,194,171,201,127, 96,241,204, 40,204,120,117, 58,228,202, 58, 28, 56,152,134,181, - 27,119,226,191,227,159, 69,183,242, 98,150, 77,159, 2,101,128,169, 7,192,217,160,204, 58,178,173,115, 22, 38,120,208,228,239, - 68,171,221,154, 71,193,209,249,255,230,218, 5,163,246,114,248,240,225,180,238,221,187,139,252,252,252,154, 45,107, 9,252,252, -252,208,189,123,247, 38, 68,111,169,204, 18, 20, 58,111,104, 8,224, 66,165, 10,229, 58, 29, 78,228, 43,177, 55, 81,137,147,197, - 65,200,229,251,160, 88,166, 65, 81, 61,137, 70, 45, 32,215, 82,112, 13,104, 99,147,152,233,245,253, 58,157, 14, 90,173, 22, 1, - 1, 1,240,244,244, 68,231,206,157,161,209,104,140,229,150, 18, 2,153,203,163,215,247,107,181, 90, 40, 20, 10, 80, 20,133,142, - 29, 59,162,164,164, 4,109,219,182, 5,143,199,131, 74,165,130, 90,173, 54,126, 47,147,233,193, 78,157, 58, 65, 32, 16, 32, 51, - 51, 19,197,197,197, 82,157, 78,135,186,186, 58,226,207, 63,255,148, 54, 52, 52,160, 83,167, 78,240,246,246,126,158,233, 24,213, -169, 83, 39,112, 72, 53, 74,178, 82, 81, 91,156, 3, 82,167,129,162,174, 2,133,127, 30,134,186,177,134,150,215,133,137,114, 67, - 35, 32, 32, 64,186,105,211, 38,163, 23,167,170,170,138,184,118,237, 26, 12,164, 77, 2,104,109, 41,225,145, 57,180, 90, 5,180, -154, 6,184,121,180,129,192,205, 31, 18,201, 22,161, 88, 44,214,174, 88,177, 34,192, 68, 30,182,110,221, 10,153, 76, 70, 47, 97, -188, 15, 43, 86,172,160,134, 15, 31, 78, 13, 28, 56,144,250,236,179,207,126,159, 50,101, 10, 38, 77,154, 4, 0,184,120,241, 98, - 93, 82, 82, 18,102,204,152, 49,229,196,137, 19,135,153,212,217,138, 21, 43,168, 17, 35, 70, 80, 47,191,249, 54,198,236, 59,133, -101,255,154,134,119, 62, 88, 8,165,186, 1,183,243,138, 32,145,236,197,111,147,135, 65,216,177,149,195,125, 99,194,132, 9,236, -184,254, 8, 17, 22, 22,214,132,244,205, 3, 1, 31,106, 42,224,232,232,104,161, 61,231, 15,205,210,183,178,102,223,220,218,103, -106,253, 91,147,247, 70, 96, 32,245, 70,224, 63,238,124,243,115, 91,158, 8,103,201,179, 98, 73, 59, 66,212, 15, 12,102, 74,132, -195, 30, 0, 0,216,181,107, 87,218,228,201,147, 69,166,201,105, 44,149, 57,130,144,144, 16, 76,158, 60, 89,180,107,215,174,180, -230,202,172,126,190,123, 8,186,123,112,225, 69, 0, 26,138,194,141, 26, 53, 18,114, 85,216,117,174, 20,127,229, 85,163, 84, 1, - 84, 41,117,200,107,160,112, 87, 69,161, 65,173, 17, 53, 71, 94,244,210, 60,181, 90, 13,133, 66,129,182,109,219,162, 79,159, 62, - 6, 69,207, 31,131, 7, 15, 54, 18, 54, 77,218,214, 8,155, 38,116,141, 70, 3,181, 90, 13,130, 32, 16, 28, 28,140,218,218, 90, - 20, 21, 21,161,186,186, 26, 93,186,116, 1,135,195,129, 90,173,134, 74,165, 50,126,198, 22,130,130,130, 68, 29, 58,116,192,181, -107,215,112,244,232, 81, 28, 58,116, 72,122,232,208,161,147,167, 79,159, 6,151,203,197,115,207, 61,135,110,221,186, 41, 96, 8, -188, 99, 32,111, 74,107,127, 31, 84,229, 95,194,223,199,127,196,181,195,155,112,227,176, 4,119,206,255, 6, 87, 14, 73,203, 43, -177, 37,231,173,183,222, 74,107,221,186,181,200,219,219, 27,217,217,217, 40, 46, 46,150,198,199,199, 11, 77, 21, 1,131, 39,128, -147,144,144,128,222,189,123,219,124, 54,181, 74, 6, 89,109, 46, 92, 92, 60,224,235,223, 67,234,225,217, 30, 63,252,240,139,144, - 32, 56, 67,233,123,188,106, 83, 33,253,239, 59,136,232,209, 96,181,109, 31, 62,124, 24,110,110,110,232,221,187, 55,186,116,233, - 66, 79, 31,104,107,106,106, 26,246,237,219,231, 27, 22, 22, 54,101,207,158, 61, 73, 76,219,110,114,242, 97,120,123,123, 98,212, -232, 33,242,176,129,253, 48,245,205,185,144, 19, 90, 84,148, 87, 99,193,162,207,177,106, 80, 8, 6,182,114, 92, 73,158, 48, 97, - 2,245,245,215, 95,179, 74,192, 99,162, 8, 88,194, 99,179, 23,192,163, 94, 85,224, 8, 1,219,139,237,149,122, 5,194,148,168, -233,178,199, 65,222,227,234, 81, 48,243, 4, 80,246,120, 0,104, 44, 91,182, 44,109,236,216,177,162,193,131, 7, 91, 45, 51,189, -214, 28, 76,239, 31, 59,118,108,147, 96, 63, 75,101,205, 90,135,174, 30,162,190,109, 3, 49, 60,192, 21,207,250,241,209, 78,192, -129, 43, 69, 65,160,210,162,147, 39, 15, 53, 20,133,171, 13, 90,228, 52,106,209,190, 85, 0,186, 60, 59,218,170, 44,218,234,167, -151,250,117,234,212, 9,253,251,247, 71, 77, 77, 13,106,107,107, 81, 91, 91, 11, 47, 47, 47, 12, 29, 58, 20,106,181,218,152, 19, -192, 26, 97,211,202,132, 70,163, 1, 65, 16, 8, 13, 13,133, 66,161, 64, 69, 69, 5,202,203,203, 81, 81, 81,129,198,198, 70,132, -134,134,130,199,227, 25,229, 89,203, 43, 96,174,148,181,110,221, 90, 20, 28, 28,140,219,183,111, 35, 37, 37, 5, 25, 25, 25,112, -119,119,199,152, 49, 99,208,191,127,255,195, 2,129, 96, 41,211,101,123,187,118,237, 74,106,221, 42,232,149,224,182,190,104,200, -251, 19, 57, 41,219, 81,146,241, 59,252, 92,117, 24, 55,118, 12,250,247,239, 63,231,221,119,223, 61,200, 68,150,183,183, 55, 6, - 14, 28, 8,138,162,112,238,220, 57,100,102,102, 74, 75, 74, 74,164, 95,125,245,149, 48, 46, 46, 78, 68,103, 78, 28, 52,104, 16, -210,211,211,109,202,155, 63,127,110,154,172, 38, 87, 84, 93,113, 5,174, 2,127,180,105,247,156, 52,168,205, 96,169,151,119,151, -195,223,172,254,126, 50, 45,111,215,187,238,216,125, 86, 5,107, 74, 79, 78, 78, 14, 2, 3, 3, 49, 98,196, 8,242,217,103,159, -133, 92, 46, 71, 99, 99, 35,214,175, 95,239,217,163, 71,143, 23,165, 82,105,146, 61,125,226,239,191,115,208,185, 83, 7,188,252, -242, 20,247,143,255,189, 24, 85,245, 50, 84, 86, 85, 34,246,157,207,241,249,212,177, 24,219,169,117,139,200,127,237,218,181,232, -211,167, 15,214,173, 91,199, 42, 1, 15, 17,166,243,254,182,240,208, 50, 1, 58,115, 85,129, 33,185,143, 83, 50, 1,218,130,121, - 34, 30,103, 40, 1,206, 36,107,103,203,115,198,171,134, 19,210, 3,155, 41, 16,132, 21,143,133, 93,120,235,173,183,210,204, 63, -103, 90,182,109,219, 54, 70, 50,233,251, 44,221,207, 84, 6,141, 29,187,246,164, 45,127,117, 38,180, 25,201, 40,144, 1,158,132, - 11, 58,123,114, 80,162, 35,192,117,229, 33,189, 92, 7, 37, 9, 4,185,114, 17, 60,104, 20,222, 93,189, 53,173, 57, 5, 64,163, -209,128,203,229,162,107,215,174, 24, 56,112, 32,234,234,234,160, 84, 42,141,235,243,213,106, 53,252,253,253, 49, 98,196, 8, 36, - 37, 37, 25,167, 4, 44, 65,167,211, 25,179, 8,246,236,217, 19, 6, 55, 61,148, 74,165,177, 63,211,158,132,158, 61,123,162,186, -186, 26, 13, 13, 13, 86,251,178, 57,153,159, 62,125, 58, 45, 38, 38,102, 76,239,222,189, 79,154, 36, 2,170, 29, 57,114,228, 73, -129, 64, 48, 91, 44, 22, 43,237,169,203,211,167, 79, 39,196,196,196,212,245,238,221,251,160,137,188,202,145, 35, 71,174,127,247, -221,119, 25,103,235, 89,184,112, 97,218,166, 77,155, 68,145,145,145,184,125,251,182,244,230,205,155, 40, 44, 44,132,151,151,151, -212,215,215, 23, 17, 17, 17,216,182,109, 27, 6, 13, 26,196,248,217,222,120,227,213,180,109,219,118,136,148,202,106,248,250,133, - 74, 61,189, 58,194,203,187, 19, 26,235, 75,146, 86,174,218,142,152,151,199, 97,215,187,238,198,122,178,100,177, 77,156, 56, 17, -201,201,201, 40, 46, 46,230, 84, 87, 87, 67,169, 84, 34, 61, 61,157,103, 80, 58,235,206,158, 61,107, 87,127,136,138,154,136, 3, - 7,146, 80, 87, 91,133,226,210,187,120,247,173,127,169,223,255,112, 5,127,234,152, 97, 24,161,170, 3, 92, 28,163,135, 9, 19, - 38, 80,159,126,250,169, 49, 29,116,112,112, 48,190,254,250,107, 0,160,142, 28, 57,194,166, 13,127, 68, 74,193,163, 84, 0,136, - 25, 51,102,152,186,208, 8, 51,119, 63, 97,175,251,223, 25,228,110, 36,249,202,237,176,149,109,207,158,224,191,202,202,237, 48, -117,197,155, 18,179,185,203,158, 9,105, 87,110,175,116,170,188, 39, 0,255, 83,131, 68,151, 97, 34,209,101,149, 86, 90,113,242, - 4, 92,180, 10, 92,174,167,144, 90,175, 5,159, 32, 16, 64, 81, 16,181,245,133, 95,155, 32, 81,135, 33, 66, 96,199, 30,155, 30, -128, 46, 93,186, 96,240,224,193, 80, 40, 20,208,104, 52,224,243,249, 70,194,166,173,244,160,160, 32, 12, 31, 62, 28, 41, 41, 41, -205,122, 0,120, 60, 30,250,247,239, 15,130, 32, 32,151,203,141,222, 5, 90,105,167,179, 11,146, 36,137,190,125,251,226,143, 63, -254,128, 61,193,149,187,118,237,146, 2, 32, 36, 18, 9, 1,192, 19,250,108,123,133, 98,177, 88,227, 72, 93,238,218,181, 43,201, - 32,207, 19,128, 63,128,106,177, 88,108,119,110,226,133, 11, 23,166, 1,192,134, 13, 27, 68, 46, 46, 46,200,207,207,135,191,191, -191, 20, 0, 74, 74, 74, 48, 97,194, 4,172, 89,179,198, 46,153,243,230,205, 73,147, 72,182, 8,213,106,153,200,173,174, 64,234, -237, 27, 12,119,207,118,112,247,108,135, 99, 39,238,129, 24,219,188,197,253,211, 79, 63, 17,243,231,207,167,170,171,171, 49,113, -226, 68,117, 64, 64, 0,159, 36, 73, 20, 22, 22,218,237, 17, 3,128, 29, 59,126, 34,196,226, 88,202,251,122, 38,222,122,235, 13, -116, 8,237,206,255,122,241, 27,228,142,141, 63,113,214,115,149, 14,181,229, 9, 19, 38, 80,203,151, 47,135,175,175, 47, 74, 75, - 75,225,230,230, 6,146, 36,225,225,225,129, 47,191,252,146, 85, 2, 30, 2,194,194,194,172,122, 1,152,166, 2,118, 58, 30,243, - 85, 5, 68,229,246, 74,139, 23, 28,180,254,137,237,149,247,203, 51,183,212,105,215, 61, 3,210,118,182, 60, 22,143, 17, 12,100, - 67,188, 20, 53, 65,232,163, 85, 73,185,119,242, 17,162,185, 11,175,128,214, 24,214,183, 7, 2,218, 7,138, 62,216,180, 51,109, -119,198, 66,155, 94,180,174, 93,187, 98,196,136, 17,198,249,120, 46,151, 11,149, 74,101, 76,221,107, 58, 77,208,177, 99, 71, 12, - 31, 62, 28,105,105,150,187,158,155,155, 27,194,194,194,192,227,241,160, 86,171,141,159, 51, 93, 58,104,186, 17, 16,135,195,193, -128, 1, 3,144,153,153,105,119, 29, 24,188, 3,245,134,163,197, 48,144,126,139, 55, 37, 48,120,136,140,253,112,211,166, 77, 66, -185, 92, 14,149, 74,133, 30, 61,122, 32, 62, 62, 94,106,223,115,197,166, 1,128, 68,178, 69,164, 80, 84,192,213,213, 15, 46,124, - 47, 41,135,195,195, 47, 9,135, 69,175,204,142,106, 86,222,214,173, 91, 9,137, 68, 66,124,251,237,183,164, 66,161, 0, 0,132, -134,134,218,149,126,217, 20, 18,201, 22, 98,219,182,173, 19,230,126,250,109,178, 94, 30,197, 9, 13,125, 6,161, 47,190,248,202, - 91,111,189,149,224,136,204, 85,171, 86,177,157,250, 49, 81, 2,154, 35,255,135,170, 0, 60,169,112,230,178, 63,115, 98,110, 41, - 81, 59, 81,158,179, 21, 6, 86, 1,113, 0,123, 14, 31, 73,107, 82,119,117,133, 56,125,187,144,241,231,163,163,163,225,231,231, -103,140,240, 39, 73,210,232,194,167, 61, 0,116,208, 31,189, 35, 96,112,112, 48, 8,130,192,238,221,187,239,147,183,118,237, 90, - 36, 38, 38, 26,239,213,233,116, 54,183, 3,230,243,249, 24, 52,104, 16,152, 68,199, 63,193,202, 90,139,219, 58,173, 8,232, 73, -125, 59,244,225, 88,164,148,137, 60,131,178, 68, 0,192,166, 77,155,168,133, 11, 23, 18, 39, 78, 56,190, 52,127,222,188,249, 71, - 12, 94, 19, 14, 73,146, 58, 14,135,227,102,239,244, 11, 13,214,186,127,188,148, 0,155, 3,181,163,251, 8,179, 96,193,130, 5, - 11, 22, 44,158, 92,112,216, 42, 96,193,130, 5, 11, 22, 44, 88, 5,128, 5, 11, 22, 44, 88,176, 96,193, 42, 0, 44, 88,176, 96, -193,130, 5, 11, 86, 1, 96,193,130, 5, 11, 22, 44, 88, 60, 21,104,178, 10,224,210,165, 75, 14, 71,112, 90, 10, 38,100,229,177, -242, 88,121, 79,165, 60,234,133, 23,197,248,253, 55, 9, 36, 18, 9,199, 82,182, 62,182,254, 88,121,157, 58,117, 50,222, 83, 88, - 88, 72,176,245,247,112,229,217,173, 0,208,157,187,153,251, 29,121,192, 39, 89,158, 35, 50, 31,247,223,219, 4, 18,137,132, 15, -192, 27,128,187,161, 61,144, 0, 42, 29, 73,158,242,128, 65, 57,235, 55, 91,169,211, 71,178,124,105,245,234,213,194,115,231,206, - 73, 79,157, 58, 5, 0, 24, 61,122, 52,134, 13, 27,198, 56,149,240,163,120, 15, 47,188, 40,198,196, 9, 3,181,128,152, 39, 22, -139, 73,176,203, 62, 89,152,161, 83,167, 78,212,228,201,193,198,243,164, 36, 80,182,148, 0, 22,143,216, 3, 96,236,225,123,239, -223, 0,130,152, 89,211,146,239, 33, 28, 32,222,135, 38,207,210,239,109,225,111,126,172,127, 47, 77,252,215, 46,159,254,113,239, -174,245, 99,219,180, 15,110, 45,147,105,224,227,227,130,178,146, 60,178,119,239,254,213, 18,137,100,176, 88, 44,190,109,143, 76, -241,156,254, 84,126, 94, 14,242, 10,148, 40,186, 75,161, 99, 91, 2,193, 93, 4,232, 22, 28, 10,201,142,236,199,165,243, 91, 82, - 36,232,189, 6, 30,250, 51, 94,185,114, 69, 26, 22,118, 20,155, 55,203,145,150, 6,124,242,201, 49, 20, 21, 21, 73, 39, 79,158, - 12,129, 64,128,210,210, 82,209,212,169, 83,225, 12,133,224,149, 87, 94,161,100, 50,153, 40, 34, 34, 2,239,188,243, 78,154, 3, -109,134, 35, 22,139, 49,113,194, 64, 50, 54, 54,150, 7,108,193,239,191, 1, 18,137,132, 96,154,179,159,197,255, 14,212,234,229, - 72, 73,137, 69,100,228, 22, 76,158,188, 10, 73, 73,250,190,199, 42, 2, 15, 7,108, 34, 32,123, 24,214,132,236, 9, 2, 32,247, -248, 61,181,191,117,253,186, 53,175, 30, 58,248, 67, 92, 72, 72,247, 30,211, 94, 28,141,142,237,189,225,235,227,138,154, 90, 37, - 74,238,118,228,220,202,175, 9, 60,116,240, 7,233,250,117,107,190,125,123,209,210,117,182,228,189,251,246, 44,225,237,156, 67, -210,242,210,108,188, 20, 5, 12, 15, 7,130, 59, 3,185, 5, 20,206, 92, 80, 32, 89,154,141, 41,227,189,169,174,161,147, 68,223, -173,223,233, 40,145, 57,211,242, 39, 44,200,126, 36, 74, 64,117,117, 53,222,121, 71,142,160, 32, 32, 58, 26, 88,185,178, 1, 89, - 89, 89,208,106,181, 16, 8, 4,104,213,170,149,244,208,161, 67,152, 63,127,190,104,235,214,173,118,213,221,194,133, 11,133, 87, -175, 94, 69,235,214,173,165,251,246,237, 35,126,249,229, 23, 0,144,166,166,166,226,141, 55,222,192,246,237,219,237,253,173,124, - 0, 72, 62,114,145, 3,108, 33,245,127,239,207,241,207,130,181,254, 1, 96,250,244,253, 72, 73,209,255,141,141,205, 3,237, 17, - 96,189, 1, 15,151,248, 77,203,205,149, 0, 54, 8,208,130, 23,224,105, 38,127,137, 68,194, 59,158,178,247, 99,209,168,129, 61, -166, 69,133,162,127,239, 86, 8,240,115, 3, 1, 2,222,158,174, 8, 13,246, 71,196,232, 46, 24, 61, 98, 64,231,227, 41,123, 63, -150, 72, 36,109,108,201,188,157,115, 72, 58, 50,188, 14,123,215, 3,115,163,129, 30, 6,207,159,135, 59,208, 51, 4,248,108, 9, - 48,180,127, 29,110,231, 28,146,182,228, 21,181,212,235, 97, 67,145,120, 36, 3,146,191,191, 63, 14, 29,114, 67, 69, 5,144,152, - 8,212,212,240, 16, 18, 18,130, 73,147, 38,209,219,189, 34, 45, 45, 13,153,153,153,210,213,171, 87, 11,153,202,141,140,140, 20, - 94,187,118, 77,202,231,243,165, 53, 53, 77, 61, 89, 10,133, 2,219,183,111,135, 72, 36,178,183, 62, 73, 0,248,253, 55, 9,146, -143, 92,228,252,254,155,164, 69,191,125,222,188,121, 20,125, 52, 87,198,176, 93, 80, 14,148, 53,139, 45,155, 55, 11,183, 44, 89, - 34,188, 52,127, 62, 85, 52,113, 34,117,126,206, 28,106,195, 59,239, 8,183,108,222, 44,108,201,111,110,105,155,177, 36,131,105, -217,131,150, 71,187,254, 39, 79, 14, 70,108,108, 74,147,191, 52, 38, 79, 14,110, 18, 31,192,226,193, 32, 44, 44,172,201, 97, 73, - 57, 96, 21,128,199,129, 5, 30, 34,174, 93, 62,189, 50, 36, 36, 36,116,240,192,182, 77, 27, 2,135, 0,159,207,133,155,128, 7, - 23, 23, 14,130,187,250, 33, 56, 56,164,213,181,203,167, 15, 73, 36, 18,171,158, 34,241,156,254, 20, 23,117, 88, 50, 23, 80,170, -128,219, 69, 64,141, 12,168,173, 3,118, 30, 4, 22,125, 10,196,173, 6,134, 13, 4, 56, 84, 29,196,115,250,179, 29,223, 4,125, -251,246, 21,253,254,123, 79,180,106, 5,204,154,197, 67,155, 54,207, 98,244,232,209,162, 67,135, 14, 17,147, 38, 77, 18, 69, 70, - 70,162,117,235,214,184,120,241, 34,246,236,217, 35,157, 62,125,186,240,251,239,191,111,150,128, 70,142, 28, 41, 84,169, 84, 82, - 23, 23,151,102,191, 91, 42,149, 98,236,216,177, 76,200,140,154, 61,123, 54, 37, 22,139,213,134,152, 17,152,144, 63, 1, 0,179, -103,207,182, 91, 65,203,200,200, 48, 30,205,149, 57,216,109,137,150,116,239, 45,155, 55, 11,187,221,188, 41,157,122,233,146,180, - 99, 78, 46,248,117,117,104,155,115, 19,194, 63,206, 75,131,178,179,165, 18, 7,149,128,140,140, 12,204,155, 55,143, 90,180,104, -145,195, 74, 4, 45,131, 73, 25, 83,121,230, 68,207,164,204, 22,104,210,167,255,170, 39,135,176, 29,254, 33, 18, 63, 19, 60,169, - 10, 0,101,225,112,154,224, 7,248,124,148,147, 31,147,178,183, 46,174, 93,207,158, 16, 26,236,111, 36,125, 75,219, 52, 11, 92, -121,208,106, 73,132, 6,251,227,218,245,236, 96, 0, 62,214,228,229,231,229, 32,106,140,254,255,163,233,192, 27, 31, 2,155,119, - 2,165,247,128,155,185, 64,214, 53, 10,169,103,129, 19,231,128,200,209,250,251, 91,160,155, 17, 15,240, 21, 63, 18,197,100,217, -178,101,105, 13, 13,250,120,203, 89,179,102,225,252,249,243,132, 68, 34, 73,163,175, 85, 87, 87,139,122,246,228, 97,254,124, 96, -192,128, 11,208,233,110, 74,139,139,139,173,122, 82, 22, 46, 92, 40, 36, 8, 66,202,116,115,152,242,242,114,155, 94,153,217,179, -103, 35, 33, 33, 1, 0,168,244,244,116,181,201,187, 32,104,226, 79, 72, 72,192,236,217,179, 31,229,120,224,104,153, 69,168,174, - 94, 69,215, 63,255, 52,108,130,164,134,150, 36, 65,106,116, 32, 53, 90, 4,157, 78, 71, 29,195,253,214,173, 17,238, 95,127,253, - 37,125,238,185,231, 30,184, 18,224,136,119,161,165,228,175,158, 28, 98,241, 72,137, 77, 97,217,249, 49,131, 69,203,174,153,224, - 55,202, 65,195,153,114,162, 60,226, 49, 24, 92,154,125, 6, 27, 65,133,148, 51,234,207,145,192, 69,137, 68,194, 75, 79, 63,210, -171, 93, 27, 79, 80, 20,112,250,124, 17,228, 10,253,174,171, 3,251,183, 65, 80,128, 27,138, 74,234,201,220,219, 53, 28, 30,143, -131,238,221,252,208,174, 93,136, 47,244, 91,180, 90, 68, 94,129, 18,195,195, 1,149, 6, 56,114, 10,144,158,167,208,174, 53,129, -110,157,128,177, 35,128, 30,193, 4,120, 92,253,214,226, 67,195,128,111, 36, 74,166,245, 77,216,249, 63, 83, 37,130,194,253,177, - 0,212, 35,106, 91, 0, 64,111,231,138,126,253,250,137,204,175,113,185, 92,105,175, 94,229,136,139,211, 63,230,138, 21, 57, 40, - 40,232,109, 85,150, 82,169,180,105,249,155,162,160,160,192,230, 61, 9, 9, 9, 70, 43,159, 86, 4, 76,174,209, 10, 2, 97,184, -246, 56, 56,237,136,150,142, 27,221, 43,171,164,106,141, 6, 28, 14, 7, 20,151, 11,146, 36,161, 33, 73,144, 58, 29,116, 58, 18, - 29,238,222,149,182,164,189,200,229,114, 0,144,206,155, 55, 15, 4, 65,216, 29,223, 97, 74,248,219,182,109, 35,154, 43,123,152, -228, 15, 0, 41,177, 41,136,220, 18,137,233,251,129,216, 20,253,255, 52,249,171, 39,135,128,159,148,203, 50,239, 67,132,169,219, -159,209,118,192,214, 86, 1,180, 96,117,128,181, 40,118, 71,162,219, 41, 27,131,187,195, 74,131, 21, 82, 37, 28,177, 34,154, 9, - 42,116, 68,158,213,207,208,223, 67, 0, 32,247,218,140, 93, 32,245,209,254,174, 0,128,162,210, 58, 40, 20, 90, 0, 64, 72, 55, - 63, 4, 5,184, 33,251, 90, 57,231,239, 91,213, 16, 8,184, 8,238,234,139, 26,153, 26, 0,172, 10, 46,186, 75, 33,184,179,254, -251,159, 31, 5,132,245, 34,224,202, 7,180, 90, 96,252, 72,192,215, 11,200, 47, 4, 34, 71, 1,157, 59,232,239,127,196, 32,204, -188, 39,143, 74,177,124, 32, 40, 47, 47,183,171, 31,214,215, 51,223,125, 55, 33, 33,129, 48, 81, 2, 76,189, 3,143,188,238,186, -117,235, 70,229,231,231, 19,142, 94, 55,135, 75, 94, 46, 84, 26, 53, 8, 46, 15, 58,138, 2, 1, 64,171, 35,161,209,146,160,116, - 58, 16,183,254,118,202,115, 95,189,122, 21,129,129,129,210,175,191,254, 90,244,193, 7, 31, 56,172, 4,152, 79,163,216, 75,220, -206, 34,255,194,194, 66,162, 83,167, 78,212,244,253, 77, 21, 2, 0,136,220, 18, 9,126, 82, 46,146,146,242,140, 43, 1,216, 88, -128, 71, 71,254, 86, 21,128, 39, 0,205,145,168,221, 4,219,194, 37,142,214,229, 62,224,213, 4,196,204, 26,123,191,131,240,241, -113, 65, 77,173, 18,129,254,238,136,158,210, 3, 90, 29, 9, 87, 87, 46,184, 28, 14, 40,138,194,164,241,193,136,138, 8, 6, 65, - 0, 85, 53, 10,248,248,184, 0, 64,181, 53,129, 29,219, 18,200,187, 67,161, 71, 48, 48,230, 57,125,101,223,204, 5,250,245, 0, -252,188,129, 9, 66,128, 36, 1, 30, 23,200,185,173,191, 63,191,136, 98,250,110,237,249,191,165, 3,201, 35, 89, 6,184,105,211, - 38,225,234,213,171,145,151,151,135,244,244,116,233, 55,223,124, 35,242,244,244, 52,110, 59,171,211,233, 68,215,175,183,146,254, -231, 63, 37, 32, 8, 2,229,229,161, 8, 13,237,130,156, 28,203, 83, 41, 36, 73, 90, 44, 31, 59,118,236,253, 94, 36,138,194,201, -147, 39,237,250,205,166, 74,192,227, 68,254,206, 80, 18, 76, 81,221,161, 61,248, 55,255, 6,229, 2,240, 73, 10, 4, 1,104,116, - 90,168, 41, 29,228, 90, 45, 20, 33, 61,128,235, 55, 91,252,236,125,250,244, 1, 65, 16, 14,145, 63, 0, 12, 30, 60, 24,219,182, -109, 35,250,245,235, 71, 53, 87,102, 11,219,182,109, 35,204, 9,223, 82,153, 61,136, 77,249,135,248, 1,220,103,249,211, 1,131, - 73, 73,121, 44, 83, 63, 2,242, 7,216, 32, 64, 83, 18, 49, 63, 90,108, 21, 82, 20,192,121,169,230,129, 61, 52,181,215, 79,255, - 29,204, 21, 24, 94, 89, 73, 94,101, 81,137,222,234, 91,179,233, 47, 92,186, 90, 14,141,134, 4, 73, 82, 6,165,133, 48,198, 6, - 20,149,212,163,172, 36,239, 54, 0,171,102,101,112, 23, 1,206,102,234,255, 15, 12, 7,178,174, 1,177, 49, 64, 72,103,189,219, -255,139,245, 0,223, 5,224,112,128,179,153,250,251, 91, 64,208,206,142,161, 48,127,223, 15,221, 26,185,126,253, 58, 4, 2,125, -157, 28, 62,124, 24, 9, 9, 9,210,180, 52, 61, 23,172, 94,189, 90,232,239,239, 47,189,113, 67,139,173, 91,129,172,172, 65,224, -114,123,136, 58,116,232, 32,178, 38,207,195,195,131,241,119,107,181,218, 39,190,227,154,146,127,183,110,221, 40,107,135,189,202, - 66, 94, 80, 43, 81,141, 90,133, 58,181, 26, 10,181, 6, 42,173, 22, 26, 74, 7,185, 70,131,122,181, 26,165,237,218,137, 90,242, -220,238,238,238,240,240,240, 16,109,219,182,141,112,196,253,111, 74,244,182,202,236, 81, 2, 6, 15, 30,108,179,140,137, 23,192, - 26,249,155, 90,255, 44, 30, 45,249,179, 10,192, 67,192,131, 94, 82, 72,237,245, 3, 5,198,138,134,182,119,239,254,165,185,183, -107, 64,146, 20, 62,124,119, 40,114,114,171,113, 35,167, 10, 4,129, 38, 1,129, 36, 73, 33,247,118, 13,122,247,238,127, 21,128, - 85, 63,113,183,224, 80, 28, 62, 9,232,116, 0,149, 15, 72,207, 3, 73, 39,128, 9,175, 3,162, 89, 64,218, 31,250,251,116, 58, -224,240, 73,253,253,143, 16,150,230,255,225, 12,101,207, 81, 84, 87, 87, 75,123,246,188,141,140, 12,224,252,121, 29, 58,116,184, -140,172,172, 44,233,228,201,147,169, 67,135, 14, 73, 83, 82, 82,112,239,222, 61, 12, 28, 56, 16, 47,189,244,146,104,255,254,253, -105,205, 37,241,161, 40, 74,100,205, 11, 96, 14, 90,241,176, 23,244, 20,192, 35,154,243,111, 2, 83,139, 62, 63, 63,159,176,118, - 88,186,191, 57,248, 13, 24,128,170,145,163, 80,173, 80,162, 70,163,130, 82,171, 69,131, 70, 7,153, 90,141,250, 49, 99, 17, 24, - 30,238,160, 87,144,192,224,193,131,209,183,111, 95,209,249,243,231,211, 90, 34,195,148,232, 45,149,181, 68, 9, 48, 29, 11, 44, -149, 49,129, 37,242,167, 45,127,243, 76,129, 44, 30, 62,249,179, 10,192,147,238,182,152, 89, 99,215, 52,128, 88, 44,214,245,238, - 55,114, 76, 94, 94,238,205, 63, 51, 75, 65,146, 20, 38,140,235,134,203,215,202,241,229,154,243,248,226,219,115, 70,242,255, 51, -179, 20,121,121,185,119,122,247, 27,249,182, 88, 44,214, 88,147, 41,217,145, 77,232,224,141,248, 31,244, 36,191,249, 11,224,191, -191, 2,162,161,192,128, 94, 64,218, 46,125,121,252, 15,128, 14,222, 45,201, 8,216,210, 85, 0,148, 13, 57,143,100, 46,178,177, -177, 17,125,251, 42,241,236,179,192,179,207, 2,131, 6, 81,200,207,207, 71, 82, 82, 18,254,248, 67,175, 61, 9,133, 66,132,135, -135, 51, 74, 15,188,127,255,254, 52, 38,196,174,213,106,225,229,229,101,183, 21,107,136,250, 55, 70,252,211,231,142, 90,176,244, -209, 92,153, 61, 74,128, 51,238, 3, 0,241,194,133,105,234, 33, 67, 68, 55,198, 71,136,202,158,121, 6,101, 46, 46, 40,235,209, - 3, 57,145,145, 34,221,115, 67, 69, 98,195, 20,141,189,120,246,217,103,209, 18,171,223, 84,134,173, 50,166,117,104,201,234,127, -246,217,103,109,150, 57, 2, 58, 71,192, 63, 73,129, 88,143,192,131, 2,147,165,128,108, 38,192, 7,104,153, 63,142,223, 33, 22, -139,171,214,175, 91,179, 54,229,232,158,247,139,239,214, 7,135,116,245, 67,212,248, 96,248,249, 10,240,255,219,187,246,248, 38, -170,109,253, 77,146,166,105,105,121, 83, 94, 90,105,121, 40,130,128,130, 88, 69,165, 81, 16, 99, 27, 64,218,136, 23,245,130,200, -105,229,120, 16,181, 66,208,123,188,162,247,120, 33, 28, 42, 92,185, 30, 72, 21,161,222,115, 84, 76, 11,150,242,176, 90, 78,234, -241, 40,120,160, 10,200, 67, 45, 45, 90,164, 64,161,208,119,210,100, 50,251,254,145, 76,153,166,121,204, 36, 83, 90,112,127,191, -223,252, 50,179,103,102,101,102,246,204,254,214, 90,123,237,181, 47,213,218,241,221,247,231,112,226,228, 37,148,151,159,248,122, -218,131,179,183, 2, 56, 21, 76,102,194,136, 84,237,151,165, 59,172, 95,151,214, 35,229, 62,224,157, 21,238, 76,128,229,191, 0, - 27, 63,118, 91,254, 46,116, 71,194,136, 84, 45, 62,251, 64, 14, 2,151,251,220, 78, 27, 5,112,230,204, 25,109,175, 94,125,173, - 7, 14,156, 7, 0,252,244, 83,119,220,126,251,205,232,211,167, 15, 52, 26, 13,206,156, 57,163, 77, 77, 77,149,148, 10,120,200, -144, 33,218, 31,127,252,209,234,207, 98, 99, 89, 22,195,134, 13,195,198,141, 27, 37,145,144,119,223,191, 96,155,132, 18, 11,224, -203, 90, 13,213,130, 13, 70,238, 82,200, 95,168, 4,180,121, 47, 14, 31, 14,187,190,195,181,208,165, 60, 55,177,255, 37,183,188, - 64,228, 47,132, 67, 63, 12,160,253,255, 87,196, 19,224, 79, 49,144, 52, 12, 48,140, 96, 57,185,199, 94,147, 16,247, 93,145,235, - 11,242,156,100,185,190,112, 2, 23,255,176,232, 5,179,217,108,254,232,232,225, 47,255,178,173,224,139,196, 1,131,135, 38, 9, -230, 2,216, 55,106,212,216,127,165, 78,159,255,114,102,102,102,147, 24,121,158,244,190, 76,230,188,177,100,203,206,159,240,223, -111,251,153, 11, 32,116,242,151,197, 97,210,213,200, 31, 0, 30,125,244, 81, 28, 58,116, 8, 79, 62,121, 0, 0, 48, 97,194, 4, - 60,242,200, 88,237,243,207, 63,223, 74,206, 95,125,245,149, 36,153,235,215,175, 47, 1,192,164,164,164, 36, 55, 52, 52, 88,149, - 74, 37, 20, 10, 5, 88,150,133, 90,173, 70, 76, 76,140, 54, 92,242, 7, 32,139, 18, 64,113,109,162,178,178,146, 41,202, 40, 34, -131, 22, 13,210, 98,136,239, 99,170, 50,138,172,212,250,239, 92,168, 36, 52,148,114, 55,188, 29, 33,143,233,226,215,215, 21,228, -241,158,128, 58,179,217,252,248,168, 49,247,240, 25, 99, 98, 0,244, 5,112, 6,128,205, 51,203,155, 36,120,187,247, 43, 78, 17, - 84,156,178, 1, 95, 30,234,236,231,208,149,242, 74,180,129,135,232, 91,175,225,200,145, 35,178,201,222,185,115,103,137, 92,247, - 39,232,247,103,188,202, 25,120, 18, 1, 81, 80,120, 43, 1,149, 75, 42,209, 85,191,189,107, 21, 98,179, 0, 2, 0, 19,234, 60, -194, 20, 20, 20, 20, 20, 20, 20, 87, 47,104, 16, 32, 5, 5, 5, 5, 5, 5, 85, 0, 40, 40, 40, 40, 40, 40, 40,168, 2, 64, 65, - 65, 65, 65, 65, 65, 65, 21, 0, 10, 10, 10, 10, 10, 10,138,107, 3,109, 70, 1, 28, 60,120, 48,228,168, 76, 95,193,132, 84, 94, -135,201, 11, 58,137, 77,103,202, 51, 24, 12,201, 0,172, 22,139, 69, 22,121,179,103,207, 78,230, 56, 78, 54,121,244,253,235, 28, -121, 11, 23, 46,156,157,153,153,249,113, 71, 94,159,217,108,142, 0,160,241,188,211,118, 0, 28, 0,146,153,153, 73,104,125, 80, -121,191, 37,121,114,121, 0,136,136, 69, 10,228,150,119,197, 64, 46,174, 34,164,113,173,232,235,243, 16,161,108,247, 43,144,135, -236,236,108,109,128,231, 41, 89,222,145,183,187, 35, 92,121, 60,102,222,190,203,154,208,189, 16, 0, 48,126,252,248,176,235,115, - 68,255, 45,184,161,223, 30, 68, 69, 69, 97,202,148, 41,157,253,126,144, 16,150,171, 89, 94,176,255,145,130,189, 29, 85, 41, 57, - 57, 57, 15,189,251,238,187, 47, 70, 68, 68,108, 83,171,213,165,106,181,250, 7, 0,102,165, 82,105, 97, 24,230, 47,102,179,185, -175,217,108,166,195,206, 40, 40,252,121, 0,124,125,228,132,248,255,198, 37,230,134, 38, 30,129,114,201,147,100,193,202,137,244, -244,116,114,226,196,137,160,228,106,177, 88,172, 70,163, 17,113,113,113, 62, 83,174,102,101,101, 89,165,144,181,197, 98,177,102, -103,103,107,179,178,178,172,251,246,237,179,122, 41, 2, 33,201,227,142,253, 39, 20, 55,191,142,247,255,238, 0, 0,112,199,254, -243,178,118,120,243,235,146,158,203,135,127,238, 70, 56, 2,124,244,169, 91,150,110,114, 4, 70, 13, 59, 10,192,173, 4,148,150, -150, 74,170,155, 85,111,107,147,107,127,174, 65,163,163,151,181,169,165, 27,116,211,106, 49,120, 0,131,132,132,185,164,190,222, -142, 45, 91,182,116, 86,131,206,132,248,110, 94, 17,121,129,190, 49, 25,191,185, 80,224, 16,190,127,121,121,121,214, 89,179,102, -105,243,243,243, 75,194, 17,250,238,187,239,234, 84, 42,213,189, 42,149,234, 81,165, 82,217, 75,161, 80,196,152, 76, 38,197,146, - 37, 75,230,187, 92, 46,176,110, 60,234,114,185,244,102,179,249, 43,143, 55,192,225,105,255, 58,188, 27,116,250,244,233, 68,236, -179, 47, 40, 40,144, 84, 33, 51,102,204, 32,225,156, 79,113,237,131,207, 8, 40,117, 58,224,160,228, 63,126,252,120,148,150,150, - 74,106,176, 2, 53, 56, 34,229,181,147,111, 52, 26, 81, 81, 81, 1,143,139, 88,182,105, 93, 73,213,120,130,168, 17, 96,122,125, -200, 0, 0,211,123, 41,147,158,158, 30,180,117, 21,146,117,117,117,181,213, 31,249, 27,141, 70,152, 76, 38, 73,228,239,217, 70, - 82, 82,146, 54, 41, 41, 41, 44,121, 60,217,243,191, 43,255, 11,109,200,127,105,154, 6,171,242,237,162,158,213, 71,107, 99,200, -232, 4, 5,154,108, 4, 47, 60,161,193,190,163, 44,108, 77, 4,205, 14, 64, 59,238, 40,142,254,228,194,248,241,227,137, 88, 37, -192,248,199,155, 72,249,119,245,136,237,174,198,128,129, 49,232,215,127, 24,126, 41,119, 96,200,205, 78, 68,104,170, 81,188,237, - 2, 30,124,240, 65,242,233,167,159,210, 6,239,234, 65,235,244,131, 22,139,197,170,215,235,145,159,159,111,245,245,189,238,223, -191,159,188,246,218,107,216,177, 99, 71,192,250,221,184,113,227,125,106,181,122,180, 90,173, 94,164, 86,171,163, 79,157, 58,133, -225,195,135, 67,169, 84, 34, 54, 54, 22, 39, 78,156, 64, 76, 76,140,106,255,254,253, 61,247,238,221,251,229, 51,207, 60, 51, 4, -192, 47, 0,212,112,119, 15,248,109,248,132,237,159,176,221,226,203, 25,134, 1, 35, 66,131,218,190,125,187, 95, 25,194,114, 41, -138,155,128,240,195, 58,191, 35,177,112,225,194,100, 79, 86, 74,138, 78, 34,253, 80, 61, 0,162,200, 95, 44,140, 70, 99,208, 99, -196, 16,151, 63,242, 95,185,114, 37,150, 45, 91,230,173,116,132, 68, 12,228,192,120,130, 62, 35,192, 36,124,200, 8, 45,254,188, -188, 60, 6, 0,248, 95,127,125, 46,222,100, 29,136,252, 61,158,129,160, 86,187,197, 98,177,122, 91,248,124,153,240, 25, 75,149, - 23,200,194, 95,154, 38,126,166,184,252,181,221,200,240, 27, 20,136,138,100,112,195, 32, 37, 46, 92,226,224,100,149,168,169, 37, -168,107, 36, 56,241, 43, 7, 40,128,190,209,135,249,231, 19,176, 81,120,249, 63,110, 76, 30, 49, 52, 17,123,207,158, 67, 66,124, - 63,140, 30,147, 8,101,100,111,220,144,112, 9,151,108,118, 84,159,117,225,215,115,118, 68,171, 42, 68,201,187, 2, 32, 50, 88, -246,178,203,243,199, 77,157, 72, 20,156,192,250,135, 70,163,209, 2,176,122,215,225,129, 3, 7, 68,145, 63, 0, 68, 68, 68,244, -212,104, 52,243, 46, 92,184, 16, 61, 98,196, 8,220,122,235,173, 80,169, 84,120,235,173,183,224,114,185,112,203, 45,183, 96,235, -214,173,216,191,127, 63, 14, 31, 62, 12,165, 82,249, 23,179,217, 60, 99,253,250,245,129,172,234,214,231, 39,135,199,210,108, 54, -107, 7, 12, 24, 96, 37,132, 4, 60,231,236,217,179,218,204,204, 76, 73, 15,148,151, 29,234,249, 60, 81, 31, 63,126, 60, 96,187, - 49,114,228, 72,173, 84, 50, 63,126,252,184,117,206,156, 57,232,209,163,135,150, 42, 2, 93, 19, 42,127,141, 79, 48, 75,189,171, -160,162,162, 2,203,150, 45, 11, 85,129,240,139,244,244,116,194, 12,202, 99,210,211, 19,136, 37,103, 34,176,249,110,194,196, 60, - 23,244,139,247, 69,214,222,164, 28,168, 91,192, 31,132, 10,197,190,125,251,172, 73, 73, 66,237, 17,236, 0, 0, 26,206, 73, 68, - 65, 84, 73,109, 92,255, 82,229,125,176, 36,198,111,227,246,216,234, 38,209,114,214,175, 95,159, 28,169, 92, 2,133, 2,136,142, - 2,106,235, 57,180, 16,130,110, 81, 12,236, 28, 96,107, 33,184,174,159, 2, 28, 11,148,157,114,161,162,162,194, 26,136,200, 22, - 63, 59, 53, 57,225,134,104,171, 90, 77,240,187,121,119,192,229, 34, 56, 91,237, 64,229,233, 90, 32,226, 20,162,122,181,224, 76, -245,207, 80,168,235,112,236, 88, 45,122,244, 10, 44,239, 10,130,241,241, 29,133,204,180,222, 19, 61,121,230,126,144, 44,239,226, -197, 41,109,182,123,247, 46, 14, 74,108, 18,149, 18, 34, 65, 73,113,241,223, 72,106,106, 42,120,210,183,217,108,173,117,200, 91, -254,133,133,133,162,234, 52, 50, 50,242,174,166,166,166,155, 70,142, 28, 9,173, 86,139,172,172, 44, 60,245,212, 83, 0, 0,167, -211,137,205,155, 55,163,180,180, 20,223,126,251, 45,182,108,217, 2,155,205, 54,140,227, 56, 93, 16,139, 93,214,247,105,231,206, -157,162,186,230, 24,134,145,252, 46, 11,101,135,114,190,231, 27, 46,153, 51,103, 14,170,170,170,124,238, 31, 52,104, 16, 66, 37, -240,170,170, 42, 84, 85, 85, 81, 69,224, 10, 67,232,238, 15,228, 13, 80, 73,181,216,229, 38,218,112,225,113,251,135,110,186,141, - 7,193, 64,128,217,225,254,112,152, 9,165, 76,122,122, 66,107,163,150,151,151,199, 32,103, 34,241,246, 4,136, 37,235,234,234, -234, 54,228, 28, 10, 89,139,133, 64,233,144,165,159, 88,224,254,247,121,240,134, 13, 27,200,249,163,207, 99,224, 8, 37,154,108, -151, 15,177,185, 8,236, 14,192,233, 41,115,178, 4, 68,225, 94,255,254,112, 41, 12, 6, 67,114, 89, 89,153,207,255,140,141,173, -179, 54,217, 20,232,219,187, 39,106, 47, 54,163,182,174, 22,251, 14,156,197,233,115, 4,234,110,205, 24, 60,172, 17,182,230, 11, - 24, 62,198,137, 33, 35, 91,176,229,157, 82, 60,252,240,195,201, 39, 79,158,164, 95,253, 85, 0,222,250,103, 24, 6,169,169,169, - 4, 0,118,236,216, 1,131,193,144,108, 52, 26,173, 82,200,223,108, 54, 71,214,214,214,206,117, 58,157,138,232,232,104,220,123, -239,189, 88,189,122, 53, 34, 34, 34,144,153,153,137,220,220, 92,148,150,150, 98,223,190,125,216,179,103, 15,190,255,254,123,244, -237,219,183, 47,203,178, 55,192,143,251, 95,232, 2, 13,214, 5,160, 80, 40, 68, 93,103, 71,118, 1,108,223,190, 93,150, 46,128, - 30, 61,122,104,171,170,170,172,254,246,133, 91,239, 84, 17,184,122, 60, 0, 87, 19, 24, 63,228, 36, 89, 11, 78, 79, 79, 39,150, -101, 39, 1,165, 26,232, 25, 1,244, 28, 2, 38,207, 35, 76,100,223,127, 7,128, 8,173,126, 0, 16, 90,254, 62, 26, 87, 36, 37, - 37,105, 3, 4, 3, 74,190,135,191,189,216,205,175, 71, 32,182, 62, 11, 63, 59, 8,206, 94,224, 0, 40, 16, 19,237,118,113, 58, - 89, 2,123, 11, 96,119, 0,246, 22,192,225, 4,236, 54,192,209,114,217, 75,226, 43, 32,229,111,111,119, 35,197,251, 26,112,125, - 66, 12, 72,132, 10, 23,108, 54, 88,191, 56,133, 99, 39, 78,227,226,197, 70,140, 26,239, 66,147,157,133,189,197, 5, 91, 51,135, -179,149,128,173, 9,216,182,109,155, 85,202, 4, 24, 20,178,121, 56,164,126,107,132,183,254, 53, 26,141,214, 98,177,148,240, 67, - 70,109, 54,155,117,194,132, 9, 82,100,177, 0,134, 1,224,198,141, 27,199,105, 52, 26, 69,110,110, 46,230,207,159,143, 21, 43, - 86,128, 16,130,111,190,249, 6, 95,124,241, 5, 14, 31, 62,140,186,186, 58, 12, 31, 62, 28,245,245,245,209, 10,133, 34, 46,152, -240,153, 51,103,250, 37, 84,169, 30,148,174,222, 5, 16,200, 11, 16,142,245, 79, 21, 1,170, 0,116, 8, 41, 26, 12, 6,173,160, -207,208, 91, 9, 96,132,214,134,199, 37, 31,146, 75,143, 39,253,188,188, 60,198,146, 51, 17, 80,171,193,228,229, 93,209,155,229, -163,254, 45, 22, 11, 99, 48, 24, 72, 48,111,136,119,108,128, 20, 66,247,133, 64,199,206,125,169, 9,131,250, 43, 48, 71,175,134, -189, 5,232, 17,203, 64,193,120,172,126, 16,216,155,129, 38, 7, 65,147,141,160,201, 78,192, 17, 64, 17, 32,230,122,238,226, 38, -220, 50,182, 2, 3,110,186,136,207,119, 87,227,226, 69, 59,198,221, 89,143, 49,189, 27,129,136, 22,216,155, 57, 84,159, 38,104, -106, 98,192,178, 12,122,247,101, 0,134,163, 95,241, 85,244,237, 10,222,213, 18,225, 47, 15,189, 94,223, 46,254,200, 71, 44, 0, - 95,233,195, 0, 28, 92,186,116,233, 93, 42,149, 42,230,253,247,223,199,166, 77,155,240,228,147, 79, 98,229,202,149, 96, 24, 6, - 63,255,252, 51,108, 54, 27,140, 70, 35, 88,150,197,211, 79, 63,205, 49, 12, 19,244, 3,144, 51,154,190,171,119, 1, 4,242, 2, -200, 97,253, 83, 80, 5, 64, 86,248,232, 71,102, 2, 28, 39,222,196,153,224,142, 80, 79, 79, 31, 76,128, 50, 88,222, 58, 9, 68, -141,104,245, 4,240, 74,129,152,110, 0,185,192, 91,243, 6,131,129, 8,173,127,222, 35, 32,220, 54, 24, 12, 16, 36,203, 33, 82, - 9,221, 27,130, 81, 0, 62,229,177, 46,160,169,153,160,197,225, 14,246,107,113, 16,168, 34, 47,239,179, 55, 3, 54, 39, 65,205, - 69,130,243,151, 8,190, 61,198,130,227, 0,131,193,160, 45, 43, 43,107, 87, 55, 44, 11, 84,157,114,224, 84,249, 37,252,115,239, - 37, 16,194,224,216, 15, 28, 82,231,176, 80,171, 8,206,159, 3,254,249, 25, 80, 95, 79, 64, 56,224,238,251, 24,104, 52,128, 78, - 55, 3,191,252,242,139,168,123,210,221, 9,178,123,111,135,196, 12,200,234, 33,242,244,249,135,141,222,189,139,187,156, 39, 97, -199,142, 29,237,202, 94,125,245, 85,178, 99,199, 14, 20, 22, 22,138,149,163, 0,112, 4,192,193,236,236,236,177, 61,123,246,140, - 1,220,110,240,247,222,123, 15,243,231,207,199,166, 77,155, 90, 45,245,236,236,108,212,214,214,162,190,190,190,177,185,185,185, -194,227, 65, 80, 7,250, 3,142,227,218,196, 67,241, 22, 60, 33, 68,180,251, 31,184, 58,186, 0,124,121, 1,228,182,254,121,153, -212,242,167, 10, 64, 88, 40, 45, 45, 13, 26,253,237,217, 47, 78, 96,100, 55, 88,134,252, 3,120, 59,129, 32,161, 27, 48,180, 5, -204,141,133, 12,222, 26,223,218,247, 31, 78, 55,128,247, 80, 64,127, 67, 3,125, 53,150,124,123,193,147,191,119, 0,160,199,138, -106, 45, 11,226, 1, 96,100, 38, 43,230,238,201,211,147, 79,159,217,109,229,250,113, 80,168,128, 8, 79,187,232,228, 8, 88, 22, -104,104, 32,112, 56, 1,214,233, 86, 10,102,204,116,123,111,252,184,236,153,164, 59,167, 39,183, 92,216,101, 29, 53,138,195,151, - 95,184,192, 40,128,243,103, 25,104,162,128, 47, 62, 5, 28, 54, 6, 12, 1,198,220, 22,129,170, 74, 14,147, 39,167,160,160,160, - 64,212,180,214,186, 59, 65, 86, 61,227,190,127,153,149, 0, 70,102, 5, 64, 22,121,193, 92,206,157, 65,254,190, 10,249,168,127, -225, 49,188,247, 46, 45, 45, 77,155,159,159,239, 79, 94, 35,128,147,223,125,247, 93,227, 61,247,220,211, 15,130, 49,253,239,189, -247, 94, 43, 33, 58,157, 78,184, 92, 46,148,149,149,161, 95,191,126, 23, 56,142, 19,165, 45,206,156, 57,211,159,165, 46,233,166, -175,134, 46, 0, 95, 94, 0, 57,173,127, 74,252,215,160, 2,224, 25,179,127, 69, 91, 24,222,202,181, 88, 44,188,197,203,248, 56, -134,240,228, 47,176,138, 37, 65, 56, 10,128, 47,147,106,249,123, 7, 0,122,208, 90,150,149,149,101,245,116,103,136,146, 39, 36, -127, 95, 49, 1, 82,229, 5,195,170,124, 59,130,201, 43, 40, 40, 40,233,211,147,193,253, 73, 17,224, 0, 56, 29, 28, 34,213,238, -199,212,208, 68,208,226, 36, 96, 93, 64,233, 17, 23, 92, 28, 65,176, 33,123, 5, 5, 5, 37,253,251, 49,152,156,172,196,195,143, - 41,209,216, 64,208, 80, 7, 52, 53, 48, 72, 24, 78,224,114, 50, 80, 41, 52,168,189,200,161,234, 87, 7,202,126, 16, 23, 48,166, -187, 19,100,237, 98, 96, 68, 60,176,238, 5, 96,209,155, 29,162, 4,200,233, 25,144, 69, 94, 7, 14,249, 11,229,217,113,190,200, -127,249,242,229,237,220,252,121,121,121,124,158,128, 18, 63,214, 63,224, 78,230,115,240,198, 27,111, 44,183,219,237,131,149, 74, -165, 38, 58, 58, 26, 0,144,159,159,143,180,180, 52,216,108, 54,216,237,118,180,180,180, 32, 38, 38,198,238,114,185, 10, 8, 33, -103, 69, 90,215,178,188, 31, 87, 75, 23,128,208, 11,192,175, 83,226,167, 10,192, 21, 35,127, 49, 50, 61,132, 79, 60,235, 0, 64, -132,195, 18, 75, 75, 75,219, 16,190, 47, 5,161, 29,148, 12,160, 86, 0, 81, 74, 32, 70, 5,180, 52,192,178, 34, 2, 88,251, 20, - 65, 84,111, 32,170,183,228,190,127, 63,228, 15, 31,100, 45,234,195,240, 38,127,239,152, 0,169,242, 36,144,127, 80,121, 53,181, -132,217, 89,226, 36, 26, 13,192,113,192, 45, 55, 42, 47,215,199,247, 46, 56, 93, 4, 46, 78,137, 89,179,102,137, 82, 78,206,157, - 39,204,238, 79, 93,132,101, 1,135,147,192,197, 2, 10, 6, 72, 78, 1, 26,106, 25,252,112,200, 6,155, 93,129,233,250, 89,216, -186,117,171, 40,242, 95,254, 20, 48,236, 58,247,246,208,193, 64, 7,121, 2, 40, 36, 32, 64,178, 31,146,146,146, 34,102, 52,128, -178,103,207,158, 7,109, 54,219, 95, 43, 42, 42,134,140, 29, 59, 54,145,101, 89, 85, 68, 68, 4, 10, 10, 10, 48,117,234, 84,216, -237,118, 52, 55, 55,163,172,172,172,190, 87,175, 94,127,183,217,108,239,115, 28,215, 4,145, 25, 0,133, 1, 9, 82, 93,255, 2, - 69,162,157,231,160, 43,118, 1, 8,189, 0,114,200, 9, 37,119, 0,197, 85,160, 0,116,134,229,239,195,250, 32, 94,215, 35,151, -149,226,215, 35, 32,214, 3, 32, 55,249,243,202,142,151,123,159, 8,203,164,202, 11, 22, 11, 32, 85, 94,147,157, 48, 77,118, 16, -133, 2,248,103,169,187,175,159, 15,248,115,247,251,207,146, 36,175,161,129, 48,140,194,147,147, 66,225,150,241,175,127, 0, 77, -141, 28, 8, 7, 76,159,158,130,173, 91,183, 6,173, 15,221,157, 32,198,199,129,158, 49, 64,213, 5, 32, 42, 18,224, 8,208, 77, - 3,188,145, 73,149, 0,137, 32, 34,190, 75,209,240, 69,254, 12,195,144,148,148, 20, 0, 64,106,106, 42, 97, 24, 38,144, 34, 16, -227,112, 56, 26, 21, 10, 69,241,160, 65,131,174,107,104,104,120,230,192,129, 3, 3,111,189,245, 86,142,101,217,230,186,186,186, -115,135, 14, 29,250, 57, 33, 33,161,188, 79,159, 62, 21, 54,155, 45,159,101,217,115, 25, 25, 25, 77,227,198,141, 19,165, 0,240, - 73,129,194,129,217,108, 22, 77,168,161,116, 1,132,115,190, 63, 47,128, 28, 47, 11, 37,255,171, 84, 1, 16, 49,214, 95,210,135, - 46, 33,119,128, 20,185,140, 32,202, 63,100,242, 98, 74,193,164, 39, 60, 72,240, 19,128,159,188,247,214,121, 22,105, 99,204, 61, -247,107,149,139, 92,189,158, 11,225,243, 12,120, 2, 4, 25,129, 55, 36, 36,121,127,123,177,155, 80, 41, 8, 69, 94,171,220,180, -180,203,117,194, 7,252, 89, 44,150,146, 80,228, 17,174,109, 29, 55,214, 3, 41, 41, 41,216,185,115, 39,195, 91, 85,162,234,227, -175, 87,156, 8, 59, 85, 94, 23,235,247,111, 99,177, 11, 55,188,201,159,143,219, 17, 6, 9,234,245,250, 64,242, 42, 29, 14, 71, - 36, 33,164,129,227, 56,179,195,225,248, 38, 62, 62,190,111,109,109, 45,243,202, 43,175,212,215,213,213,213, 12, 30, 60,184,161, -177,177,177,201,225,112,212, 59,157,206,150, 5, 11, 22,216, 36, 90,216, 97, 63,204,204,204,204, 14, 35,194,142,148, 77,241,219, - 84, 0,228,110, 61, 58,172, 53,242,144, 40,227,203, 90,150, 2,153,163,250,197,100, 11, 12,235, 15,164, 76,250, 35,135, 55, 32, -132, 58,241,187, 29,174,188,157, 59,119, 74,170,171, 14,176,238,127,107,242,228,148,205, 0, 64, 78, 78, 14, 81, 40, 20,224, 23, -161, 11, 91,167,211,129,227, 56,112, 28,135,140,140, 12, 38,200,168, 0,134,101,217,104, 66,136,139,227,184, 22,167,211,249, 15, -165, 82,201, 40, 20,138, 72, 0,145, 28,199,193,229,114, 41, 89,150, 85,179, 44, 59,112,193,130, 5,199, 5,231,118,248, 36, 64, - 20, 20, 93, 1,129,114,164, 48,161,206, 35, 76, 65, 65, 65,209, 5,208, 44, 32,116, 78, 96,216,168, 4,229,103, 0,244, 0,160, -161,196, 79, 65, 17,216, 3, 64, 65, 65, 65,113,181, 64,227, 81, 2, 56, 1,241, 43,112,121,230, 65, 21,128,129,158,117,154, 53, -138,130,130, 42, 0, 20, 20, 20,215, 8, 20, 0, 98, 4,219, 60,241,171, 5,164,207,121,142,163,214, 63, 5, 5, 85, 0, 40, 40, - 40,126, 35,109, 26, 37,125, 10,138, 0,218, 51, 5, 5, 5, 5, 5, 5,197,111, 89, 91, 62,120,240,160,112, 34, 29,226,149, 68, -135,160,237, 68, 59,149, 22,139, 37,158,223,246, 21, 76, 40,148, 39, 21,215,162, 60, 31,195, 22, 25,250,252,104,125, 92, 45,242, -226,227,227, 91,143,169,172,172,100,164,202, 91,184,112, 33, 50, 51, 51, 25,250,254,133, 38,147,126,191, 84,158, 20,121,146, 21, - 0,137,232, 39,242, 56, 98, 48, 24, 36,103,150,242, 55, 95, 60,218,143,153,246, 53, 27,160,175, 99,174, 56,120,130,241,140,133, -183, 90, 44,150,214,108, 93, 93,101,172,182, 94,175, 79, 46, 44, 44,108, 37,193,148,148, 20,237,206,157, 59, 75,174, 69,109,215, - 87,125, 28, 63,238, 30, 25, 54,114,228,200,206,190, 60, 50, 99,102, 38, 10, 62, 49,251,124,103,103,204,204, 36,158,125,126, 95, -156, 25, 51, 51, 3, 54, 2, 5,159,152, 67,126,233,226,227,227,137, 94, 63,180,117,187,176, 16, 36,152, 18, 16, 12,171,179, 87, - 39,111,255,108, 59, 18, 71, 37, 90,193, 0,199,191, 59,166,189,115,220, 93, 88,251,230, 90, 73,239,223,220,185,115,219,221,119, -110,110, 46, 77,238, 68, 65,209,129, 10,128, 90,236,129, 73, 73, 73,146,133, 7, 80, 0,124,146,168,247, 68, 27, 18,136, 54, 20, -205, 73, 76,227, 66, 44, 22, 11,140, 70, 35, 76, 38,147, 53, 64,154, 78, 49,255,223,230,152,193, 9,215, 3, 0,206,217,237, 96, -109, 45,238,194,218,122,158,228,196,165, 63,110,109,200, 11,219,228, 20,240,228, 22,151, 52,199,187,130,113,103,215,227,127,129, -160,235,157,209, 56,183,169, 15,158,248,195,168, 15, 57,239,129,204,152,153,137,135,116,183,217,129, 76,141,135,232, 67,250, 15, -129, 2, 33, 59, 28, 14, 35,138,138, 50, 48,109, 90, 14,244,122, 19, 10, 11,221,207, 42, 20, 69,224,137,103,159, 32,181,189, 47, - 98,141,121, 53,122, 69,247, 2,199,186, 96, 39, 45,214, 79,191,249,108,218,108,215, 35,228,174,196, 73,218,197,139, 23, 7, 85, - 4,230,206,157, 75, 22, 46, 92,232,243,153, 82, 37,128,226,183,140,131, 7, 15,122,123, 9,218, 29, 19, 78, 12,128,164,115,189, -167,175,149, 11, 27,204,230,228,176, 91, 95, 66, 68, 47, 98, 69, 26,141, 70, 16, 66,176,114,229,202, 64,231, 17,201,249,187,123, -118,199,225,138,143, 80, 86,241, 79, 92,170,250, 31,148,255, 57, 3, 91,159, 78,235,212, 23,237,240,247, 71, 90, 73,254,200, 17, -247, 58,112,121, 93, 88,206, 17,209,117, 34, 10, 82,234,227,248,241,227,152, 55,111, 30, 2,146,191, 8,133,241,254,251,119,135, -170, 56,250,197, 67,186,219,154, 51, 50, 50, 52, 15,233,110, 11,153,216, 61, 22,126,160, 37,100,235, 31, 0,210,210,220,179,242, -165,165,229,163,176,176, 28,122,253, 80,232,245, 67,219,116, 13, 4,253, 94, 55,108, 72,158,253,252, 35,228,119,127,152,143,151, -103, 46,197,109,241,183, 99, 72,247, 33, 24,210,107, 8, 70,197,221,130, 63, 76,249,125,209, 75, 47, 44,195,222,234,175,173,107, -214,172, 17,245,109, 95,184,112,161,205,114,199, 72, 27, 54, 47,254, 10,179,103,207, 38,194, 37,156,250,209,233,116,178,214,183, -220,242, 58, 18, 11, 23, 46, 76,150, 67,134, 12,114,250, 0, 24, 15,224, 37, 0,107, 1, 20, 1, 48, 1,248, 47,207,114, 19,165, -125,223,228,239,175,172,141, 7,192,104, 52,146,138,138, 10, 0, 64, 98, 98, 34,132,147,205, 88, 44,150, 54,219,222,251, 3, 89, -236,213,213,213, 86,139,197, 34,218, 19, 16, 76, 89, 16, 90,245, 79,123, 82, 97,122, 91,250, 82, 93,236, 57, 57, 57, 65,143, 41, - 46, 22, 53,183, 58, 49, 24, 12, 88,185,114,165,207,157,203,150, 45,131,201,100,130,209,104,244,123,140, 47, 12, 78,184, 30,167, - 47,213, 97,235,211,105,232,195, 76, 66,249, 59, 47, 34,241,225, 68,124, 94, 94,131, 89, 43, 55,117,234,203, 54,230,150,209,173, -235,163, 71,143,110, 83,206,123, 6,132,229,114, 91,246, 65,200,141, 24, 12, 6,204,155, 55,207,231,206,205,155, 55,195,100, 50, - 65, 55,233, 86,236,254,234, 59, 32,182, 27, 80,223,120,197,159,225,174,221,223, 70, 3, 57,216,181,251, 91, 89,228,157,251,115, -159,128, 4,211,127, 73,141,168, 15, 68,232,250,207,200, 40,130, 94, 63,180,245,151,135, 94, 63, 84,116,151,192, 59, 31,190,131, - 21,111,255, 9,247, 12, 79,134,171,165, 5,172,139, 5,163, 98, 0, 40, 65,192,225,220,249, 42,140,236,119, 19, 94,126,250,101, -252,105,213,159, 68,121,163,188, 27,182,148, 65,155, 1, 0, 91,182,108,105,115,238,236,217,179,137,119,153, 88,178,222,245,202, -110, 60, 4, 29,217,189,123,119,216, 94, 5,157, 78, 71, 86,173, 90, 5, 0,178,200,235, 72,226,175,171,171,227,189,101, 97, 93, -103, 93, 93, 29,223,166,135, 42, 39, 6,192,191, 1,248, 14,192,251, 0,166, 2,120, 16,192,239,225,158, 21, 18, 0, 46, 80,234, -111,139, 12,163,155, 99,114, 76,203,130, 91,241, 38,147,137,177, 88, 44,140,197, 98, 97, 42, 42, 42,192,175,243, 46,101,225,182, -175,253,254,192, 43, 21, 89, 89, 89,214,234,234,106,171, 47, 5, 65,184, 29, 36, 85,174, 47,171, 38,208,246, 21,255,192, 62,254, -248, 99,159,196,207, 48, 76, 59,242, 95,182,108,153, 40,153,191, 86, 84,162,241,189,197,152,181, 33, 31,131, 19,174, 71,255, 62, - 81,168,216, 86,225, 38,255,158,221,221, 7, 69, 40, 37, 95,171, 94,175,215, 6,218, 22, 3,142, 0,215, 69, 3,219, 51,129,184, - 72, 96, 84,175,203,110,255,248,110,192, 39, 25,151,203,165,130, 97, 24,159,139, 20,188,254,250,235, 62,137,127,228,200,145, 48, -153, 76, 88, 53, 47, 21, 71,202, 79, 97, 64,226, 64,160,169, 89,140,245, 15,145, 94, 0,209, 86, 94,193, 39,102,236,218,253,173, - 79, 75, 95,208,183, 47,233,198, 87,125, 64,252, 46,161,128, 39,125,254,215,161, 31, 38,233,252,102, 91, 51, 38,205,190,203,154, - 52,240, 14,180, 52, 53, 1, 74, 37, 84, 42, 21,148, 74, 37,148, 74, 21, 78,158, 60,137,173,219, 10, 78,219,157,205, 24, 18, 25, -143, 91, 39,143,155, 50,255,119,243, 37, 91,141,111,236,154,135, 7,140, 9,237,202,183,108,217,194, 72,245, 4,240,228,143, 33, -107,176,235,149,221, 97, 91,238, 58,157,142,172, 93,187, 22,163, 71,143,198,186,117,235,186,164, 39, 96,225,194,133,201,115,230, -204, 33,199,143, 31,183, 86, 85, 85,201, 34,175,170,170, 10, 85, 85, 85,225,120, 19,180, 0, 38, 3, 56, 4,224, 52,128, 1, 0, -126, 4,240, 11,128, 83,158,197, 6,138, 86,133,152, 39,127,225,186,183,178,124, 69,242, 0, 8,250, 94, 81, 81, 81,129,184,184, -184,118, 10, 2, 95,230, 75, 65, 16,217,184,134, 28,252,247,200, 35,143,116,216,189, 11,201,202,151,213,239,153, 56,136, 9, 70, - 22, 54, 84,162,241,225, 59, 64, 98, 95, 4,166,188,130, 70,124, 8,188,235,182, 22,137,229, 69, 68,252,251, 58,176,172,244, 68, -103,133,133,133, 37,194,231, 20, 36,247,186,111, 15,207,123,192,107, 27,128,235,175, 3,206,237, 80, 35,119,163, 3,243, 62,242, - 95, 46,201,188,151,121, 62,123, 97,176,223,153, 79, 86, 34,118,148, 6, 49,195,159,195,199, 43, 23, 96,236,232, 1,184, 49,245, - 79,162,234, 67,204,165,223,127,255,110,236,217,163, 19,211,151,207, 0, 32, 94,228,207,240,129,127,161,244,235,139,181,240,197, -192, 31,209, 23,121,121, 2,130,225, 76,245, 25, 60, 96,120, 0,177,221,123,193,197,176,248,242,139,127,160,161,177, 17,250,233, -211,113,190,186, 26,121,249, 91,241,212,147,243, 6, 71,106, 34,161, 32, 17,152,118,219,180,226, 31,173,235, 66,178, 26, 47, 93, -186, 20,246,125, 11,201, 31,128, 71, 9,120, 62,100, 79,128, 78,167, 35,203,151, 47,199,176, 97,238,231, 57,116,232, 80,116, 37, - 79,128,151,197, 47, 27, 4,214, 63,191, 30,202,189,222,236,249, 38, 35, 0, 68, 3, 24, 5,224, 24,128,193, 0,234, 1,212, 66, -254, 73,186,174,121, 92,177, 68, 64,113,113,113, 90,131,193,208,174, 43,192, 51,183, 61, 0,180,206,119, 47,149, 28, 66, 12,254, - 19,235,113, 8, 25,188,117,239,207,221, 47,214,250, 7,128, 79, 95, 90, 14,253,138, 55,193, 78,153, 4, 21,128,152,189, 39,240, -121,121, 13, 0,128,157,178, 8,206,239,251,130,233,247,123,201, 36, 21,128,144, 68,163,102,230,135, 88,244,228, 41,252,244,244, - 82, 52,237,113, 96, 64,223,192,229,161, 42, 80,225, 42, 7,155, 55,111,118,107,195,250,123,177,175,170, 26,177, 99, 99,113,186, -168, 28,208, 68, 34,109,209,191,163,247,117,169,157,249, 45,250,139,250, 15,169, 78, 2,120, 17,124,121, 31, 2,202, 46,202, 40, -194,180,156,105, 72,203, 7, 50,138,220,235, 69, 25, 69,173,202,129,186,240,132,168,107,104,180, 55,160,111, 84, 31,176,246,102, - 16, 5,193,237, 19, 39, 98,219,182,109,246,181,111,190,169,225, 8,193, 99,143, 63,134,222,125,122,163,185,177, 17,172,139, 69, -108, 68,119, 56, 21,206,144,238,183,182,182,182,205,232, 0,169, 1,129,237,200,159, 71,136, 74,128, 78,167, 35, 70,163, 17, 19, - 39, 78,108, 83, 62,122,244,104,188,241,198, 27,157,170, 4,116, 20,241,243,178,133,114,121, 47, 64, 8, 83, 5,127, 3,224,160, -135,236, 31, 4,240, 0,128, 50, 0, 99, 0, 20, 0,216, 4,192, 9,138,176, 20, 0,226, 69,138, 68,226,254,128, 72, 76, 76,108, - 37,253,164,164, 36, 45, 31, 27,192,123, 7, 18, 19, 19,173,124,119, 65,103, 53,188,114, 34, 88, 95,191,192,250, 15,138, 89, 27, -242, 65,166, 39,224,220,157,183,161, 15, 38, 33, 42,109, 29,216, 51,231,129,158,221,161,170,249, 16, 59,214,150, 2, 74,101, 40, -247, 30,182,214,124,232,133,127,195,132,113, 64,226,162, 35, 24, 21,243, 36,126,188,193, 0,252,239, 82,191,229,157,229, 1, 48, -153, 76,184,231,246, 27, 49,101,210, 8,232,111, 89,138,236,181,235,113,172,244, 52,158,190,111, 2,206, 22,236, 66,221,165,122, -185,222,135, 54, 93, 5, 30, 47, 64, 80,130, 22, 18,190,156,228,239, 71,166, 40, 84, 86, 86, 50,241,241,241,196, 19,255,215,170, - 16, 0,192,180,156,105, 80, 23,158, 64, 97, 97,121,235, 72,128,192, 1,129, 12, 56,142,131,139, 3, 8,199, 34, 50, 74,131,199, -159,120, 66,243,218,171,175,162,127,255,254,220,224, 1, 3, 20,246,166, 70,184, 8, 64, 56, 23, 56, 46,184, 71, 43, 55, 55,151, -153, 58,117, 42,169,169,169, 65,125,125,125, 27,197,209,107,116,128,232, 81, 1, 58,157,142,100, 47, 56, 10,104,134, 1,103,223, -110,127,128,102, 24,178, 23, 28, 5, 68, 42, 1, 58,157,142,204,152, 49, 67, 59,122,244,104,107, 77, 77, 77,187,253,241,241,241, -152, 49, 99,134, 22, 93, 60, 38, 32, 92,235, 63, 76, 47,128, 80, 97, 24, 8,119, 87,192,195, 0,154, 64, 33,155, 2, 32, 37, 17, -144,175,253, 62, 97, 48, 24,124,122, 1,120,178,143,139,139,211, 26,141, 70,171,135, 16, 97, 48, 24, 2, 6, 21, 6,178, 14, 67, - 24, 95,223, 33,195, 0,121,235, 62, 80, 48,160, 20,148,255, 57, 3, 17,105,235, 96,171,250, 9,170,189,235,224,204, 95, 4,230, -161,213,216,254,251,116,252,178,253, 36,244,171,222, 7, 84,157,147,217,121,169, 5, 40, 90,181, 13,163,126,153, 6, 92,104,194, -146,169, 75, 3,150,203,225, 1, 8,213,250, 47,216,182, 28,202,193, 55, 35, 6, 35, 80,249, 69, 14, 26, 24,130,127,253,116, 10, - 83,142,156, 22,117, 57,123,246,232,252,146, 61, 0,120,246,251, 60, 78, 44,249,251,121, 71,195, 34,134,112,114, 0,240,200, 40, -186, 76,252, 0,218, 89,254,124,192, 96, 97, 97,185,207,243, 99,163, 98, 81, 85, 87,133,137, 67,238,128,173,197, 14,216,236, 96, - 29, 78,188,108, 52,130, 81, 64,209,220,212, 8,142,115,129,117, 17, 68,170, 34,112,190,241, 60, 34, 92,193, 71, 27,127,254,249, -231,173,247, 54,119,238, 92,194,183, 55, 23, 46, 92,142, 9, 59,115,230,140,232,251,116,147,176, 91, 9, 24,153,208,254,255,143, -159,116, 32,235,221, 81, 16, 75,214,158,227,200,196,137, 19, 17, 31, 31,223,110,255,145, 35, 71, 80, 80, 80, 96,237, 44,242,247, - 88,227, 12,239, 9,144,163,223,223,151,245, 47,131, 23,128,199, 3, 30,133,160,133, 82,184,188, 10, 64,135,128,183,252, 1, 32, - 41, 41, 73,107,177, 88,172,188,235,223,143,114,160, 45, 43, 43, 11, 22, 11,192,200,101,205, 75, 33, 19,177, 10, 6,111,253,251, - 34,126, 94,209,145,114,189,135,202,107,224,252,254, 53,156,195, 87, 24,240,208,106,160,174, 30,229, 57, 47, 98,232,194, 53, 56, -187,233, 69, 32, 66, 5, 40, 58, 39,179,115,101, 19, 48, 50,238, 97,209,229,157,225, 1, 48,153, 76,141,179,167,220,113,166, 7, -215,235,250,102, 68,104,242,215, 44,194, 95,118, 28,196,146, 7,239,198,188, 55, 63, 64,250,127,255, 95,135,122,131, 2,221, 98, -193, 39,102,120,146, 0, 49,225, 42,167,225,184,250, 3,121, 1, 50,138,138,136, 47,242, 23, 90,255,193, 48, 40,110, 16, 62,253, -178, 8,119, 93,127, 23,162,187,197,128,227, 8, 20,132, 5,199, 48, 32,132,192, 69, 0,150, 35, 96, 89, 22,182,186, 38,236,220, -191, 19,106,151, 90,114, 80,170,119,160,211,127, 44,154,132,148, 65, 21, 96, 62, 19, 47,195,159, 18, 32,149,252,189,149,128, 85, -171, 86, 97,224,192,129,151, 21,251,242,114,152, 76, 38,116, 5,203, 95,110, 69,192,151,245, 31,166, 23, 0, 0,146, 1,220, 0, -224,143,184, 60,241, 19, 69, 87, 86, 0,226,226,226,180,222, 30, 1,190,223, 93,168, 28, 8,215,195,180,224, 37,191, 88, 50, 14, - 3,244,105,253,135, 74,252, 60,102,173,220,132,173, 0, 30, 92,145, 2, 98,121, 17,204, 35,217, 56, 84, 94, 3,166,119, 47,156, -248,181,222,109,253, 75,239, 2,144, 5, 71,142, 28,105, 29,242, 39,102, 93, 14, 15,128, 20,229, 96,243,230,205, 14, 0, 13, 11, -146,199,212, 63,183,250,127, 28, 47,189,108,180,247,235, 30, 87,115,244, 88,101,255,121,199, 62,136,233, 36,226, 23, 67,206,194, - 46, 26,209, 94,128,142, 74, 6,228,139,252,121,203, 31, 64,208,128,192,197,139, 23, 51,119,221,127,215,116,235,164,146, 2,195, - 45,233,168,183,215,131, 81, 0,238,193, 72, 28, 92, 46, 2,142,101,209, 45, 50, 22, 95,215,125,135,178,189, 39,144,103,206, 43, - 9,251,194,203,127, 7, 64,250, 48,192, 54, 74,192,192, 74, 28, 63, 19, 31, 18,249,123, 43, 1,235,214,173, 67,207,158, 61, 81, - 83, 83,131,229,203,151,163,171,185,253,229, 80, 4,252, 89,255, 33,122, 1,250,195, 29,245,175, 0,112, 43,128, 44, 0,229,148, -190,101, 86, 0, 58, 42, 15,128, 63,143, 64,118,118,182,214, 91, 81, 48, 24, 12,146, 19, 6, 9,137,160, 43,164,216, 21, 90,255, - 66,226, 55, 26,141,124,183,135,240,185,138,190, 96, 94, 9,120,120,197,123, 32,249, 64,223,121,102,148, 60,151,142,187, 77,127, - 3, 34, 34,208, 77,163,238,148,251, 21,142,241,247,181, 30, 98, 30, 0, 22,128,194, 83,183,138, 48,235,227,220,236, 41,119, 84, - 61,151, 83,152,240,242, 83, 15,116, 31, 52, 32,217, 1,224,176,193, 96,232, 1,247,248,226,144,234,131,127,229,246,236,209,241, - 17,255,161, 40,119, 76, 48, 11, 94, 10,161,203,225,234,151, 2,111,210,231, 61, 2,189,123,247,246,169,157,125,189,231,235,237, -241, 55, 93, 15,215,108,246,240,228,235, 39,143,233, 19,219, 7,118,167, 29,132, 16,168, 85,106,212,218,154,177,239,215, 61,216, -252,215, 92,104,111,214,106,243,144, 23,246, 53,190,177,107, 30,114,115,115, 81, 86, 38, 61, 7,192,101, 37, 0, 97,145,191, 80, -222,162, 69,139,200,170, 85,171,176,116,233, 82,116,229, 62,127,161, 34, 80, 82, 82, 18,210,185,129,142,145, 32,115, 6,220,227, -253,237, 0, 94, 0,176, 31,128,139,210,183,111,140, 27, 55, 14, 7, 15, 30, 68,142,105, 89,187, 60, 0,222,217, 0, 85, 94, 13, -101,192, 62,126,225,182,247,126, 41,147, 17, 4, 34,250, 16,189, 0, 97,161,163,134, 1,242,202,136,217,108, 70,113,113, 49, 87, - 81, 81, 33, 36, 50,173,197, 98,145,108,221,204, 90,185, 9, 16, 36,254,153,252,242,134,214,245, 78,138,134, 9,218,128,113, 36, -164,103,183, 22,192, 69,184,135,255, 60, 30,230, 53,158, 93,144, 60,166,101,106,241, 55,221, 31,123,245,125,152,205,102,117,113, -113,241, 64,180, 77,103, 29, 82,125,116,180, 39, 32, 88,126,255,160, 45,103, 7,116, 9,248, 35,127,135,126, 24, 80, 24,220, 48, -251,232,237, 45, 76, 55,101, 12,217, 27,191, 15,147,238,152,132,193,177,131, 1,142,224,188,189, 6, 95,127,251, 53,206, 30, 61, -139,251, 70,222,167,125,246,217,103, 59,189, 62,132, 74,128, 92,100,205,123, 2,174,150,128,191, 48,250,234,229, 66,142,103,161, -144,250,224, 76,203,196,123, 0, 58, 10, 89, 89, 89, 62,201,222,107, 38, 54, 33,172,190,242, 22, 7, 35,218, 80,209, 17,195, 0, - 77, 38, 19,204,102, 51, 91, 92, 92,172,242,116, 29,240,228,127, 95,128,251,246, 9,207,100, 74, 29,145, 74,153, 4, 40,239,148, -198,201,108, 54, 71,122,222,203, 87, 60, 69,174,204,204,204, 39,194, 20, 27, 57,245,143,239,148,154,205,230,123,139,139,139, 81, - 92, 92,108, 7,160,241, 44,114, 16, 63, 35,114,188,191,100,146,246,236,111, 83, 95, 82,137, 91,142, 46,129,202,202, 74,166, 40, -163,136, 12, 90, 52, 72,139, 33,190,143,169,202, 40,178,138,141, 7,216,248,214, 70,102,205,154, 53,201,155, 86,108, 66,252,176, - 27,172, 0,240,227,145, 31,180,169, 83,245, 88,187,126,109,201, 71,248, 40,164,235,204,205,205,101, 30,120,224,129,118,163, 2, -156,206,240, 70,136,201, 77,214,215, 90,180, 63, 69,215,244, 2,120,151,137, 86, 0,130, 89,226, 18, 44,245, 80, 95,116,210,193, -242,229, 58,223,167, 60,131,193, 64,138,139,139, 85,194,231, 37,244,176, 72, 84, 80, 74, 58,136,144,187, 98, 35, 20, 11,160, 17, - 32, 4,238,196,252, 81, 8,111,124, 47, 95, 31, 63, 23, 23, 23,243,227,202,234, 19, 19, 19,251,153, 76,166,200,174,240, 44, 59, -210,109, 47,167,236,202,202, 74,166,114, 73,165,108,207,224,249,231,159, 47,241, 62,239,235,191,239, 13,251, 58, 63,251,236, 51, - 74,174, 20, 84, 9, 16, 97, 68, 51,161,206, 35, 76, 65, 65, 65, 65, 65, 65,113,245, 66, 65, 31, 1, 5, 5, 5, 5, 5, 5, 85, - 0, 40, 40, 40, 40, 40, 40, 40,126, 3,248,127, 37, 93,196,116, 64, 61,103,188, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, + 1, 0, 8, 6, 0, 0, 0,197,144,206,103, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,189,167,147, 0, 0, 0, + 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,215, 12, 29, 10, 35, + 1, 96, 85, 38, 85, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,125,121, 92, 84, 85,255,255,251,220,217,217, 23, 1, 21,151,193, +125, 95,201, 37, 55, 40, 53,243,155,153, 6,148,154,100,101, 98,137,218,147,166, 61,101,143,250,211, 71,197,164, 50, 53,161,167, +210,172, 52, 5,115,201, 45, 81, 7,245, 81, 82,113, 47, 23, 20, 69, 4, 69,150, 97, 22,102,187,115,151,223, 31, 51, 67, 3, 2, +179,128, 91,207,188, 95,220,215,229,222,123,238,103,206, 61,219,103, 61,231,144, 30, 61,122,240,240,192, 3, 15, 60,240,192, 3, + 15,254,167, 64,121,138,192, 3, 15, 60,240,192, 3, 15,254,119,112,230,236, 1, 0, 0,241, 88, 0, 60,240,192, 3, 15, 60,240, +192, 99, 1,240,192, 3, 15, 60,240,192, 3, 15, 60, 2,128, 7, 30,120,224,129, 7, 30,120,224, 17, 0, 60,240,192, 3, 15, 60, +240,192,131,191, 5,132,246, 23,231,206,157, 35,238, 18,170, 41,150,192, 67,207, 67,175, 54,164,166,166,242,107,215,174,125,100, +249, 27, 55,110, 28,191,105,211, 38,226,169,143, 39,154, 30,234, 65, 15,158,242,243,208,251, 59,211,115, 89, 0,248, 31, 71,245, + 2, 36,143,115, 62, 83, 82, 82, 48,117,234, 84,226,169, 54,247,235,120,216,176, 97,149,215, 25, 25, 25,127,139,178, 28,253, 82, + 66,157, 3,193,142,237,169,127,235, 54, 35, 11,220, 6,169,177, 13, 34, 64,163, 2,123,145, 99,152,247, 56,183, 69, 79,255,245, +224,241,177, 0, 60,140,198, 58,122,244,232,168, 29, 59,118, 40,236,174,163,119,236,216,145,249, 88,244, 72,222, 50,118, 18,242, +216,246, 75, 62, 47, 47, 15, 0, 32,151,203,159,164, 65,196,105,233,116,220,184,113, 78,167,221,180,105,147, 43,130, 26,191,101, +203,150,202,139,109,219,182, 97,216,176, 97, 85,158, 63, 42, 33, 32, 59, 59,155, 7,128,200,200, 72,210, 16,233,118,108, 79,125, +160,245, 23, 30,209, 28, 0,112,207,104, 4, 99, 48, 89,110,170, 52, 0,128,216,216, 88,164,165,165,213,154,191,222,185,189,249, +182,119,219,186,244,227, 63, 15,252,217,137,122,145, 33,240,221,139, 48,238,216,134,242,242, 49, 40, 7,208, 75,246, 41,230,201, + 78,163,185, 20, 40, 49,230, 98,158, 33,206,165,223,141,141,141,141, 74, 75, 75, 83, 84,187, 23,157,150,150,150,249,152,245,173, + 6,105,183, 79,200,247, 54, 56,154, 4, 75,136,143,200,159,152,164, 98,222,164, 50, 80, 21, 6, 13,167, 51,153,255, 39,102,199, + 57, 20, 0,172, 12,219,118,174,111, 67,224,119,236,216,129,133, 91, 22,195,167,185, 63, 42,110,171, 49, 63,110,158,226, 49,215, +184, 31, 39, 16,185, 92,206,231,229,229, 33, 47, 47, 15,251,246,237,195,212,169, 83, 31, 87, 33,192,214,129, 72,106,106,170, 40, + 33, 33,193,188,124,249,242, 83, 0, 48,103,206,156,167,234,122,113,204,152, 49,149,255, 51, 12, 11,218,108, 2,109,162, 65,211, +150,131, 97, 24,204,153, 51,199,165,188,216, 51,255,154, 96, 21, 6,248, 71,105, 9,112, 69,248,121,100, 26,126,128, 31, 46,220, +248, 25, 50, 52, 3,139, 99, 40,254,230, 12,206,231,150, 97,236,178,117, 78,189,222,246,110, 91, 39, 25,186, 5,175,254,247, 85, +135,101, 34, 27, 57, 15, 65,163,223, 66,225,123,189, 0, 67,121,229,253, 51,134, 15,112, 6, 0, 12,192, 96, 89, 44, 14, 6,158, + 70, 0,128,222,229,189,157,106, 51,105,105,105,247,221,180, 99,144,228, 49,234, 99, 13, 49, 6, 60, 9,223,219,160, 24,208,173, + 7,121, 45, 60, 66,168,106,209, 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195, 89, 39, + 73,221,113,225,103,155, 58,145,102,150, 11,244,146, 31,168, 0,176, 99,199, 14,197,150, 79, 62, 66,220,162, 37,138,122, 54, 2, +222,198,248, 1,160, 84, 95, 6, 4, 3,255, 60,184, 0,154, 27,229, 88,243,246,202,199,141,145,213, 54,240, 60,234, 60, 86, 10, + 1, 35, 70,140, 64, 94, 94, 30,228,114,249, 99, 87,118, 10,133,101,220,136,142,142,230, 1, 80,169,169,169,225, 9, 9, 9,133, +203,151, 47, 63,237, 44, 17,134, 97, 64,211,230, 74,198,111,207,252,179,179,179, 17, 25, 25,233, 82,166,226,226,226,236,153, 45, + 50, 50, 50,170, 11, 0, 13,209, 86, 92,174,135,200,200, 72, 50,110,220, 56,126,248,240,225,247, 61,219,191,127,191,205,210, 97, +179,122, 56, 77,191, 33,221, 1,225, 17,205, 81, 88,174,198, 47, 83, 95, 70, 48, 25,128,220,255,204, 70,171, 49,173,144,225, 2, +243,175, 44, 44,171,169,141, 52,128,169, 45,124,203, 49,232,111, 85,160, 48, 33,162,206,116, 23,165, 7,176,176,235, 61, 44,189, +248,113,125,235,179, 33,152,110, 67,210, 64, 3,211,122, 16,223,219, 32,136,143,143,247, 2,240, 52, 0, 31,187,219, 42, 0, 23, + 54,108,216,160,116,150,206, 23,107,191,160,232, 82,147,136, 54, 25,165,229, 48, 75, 69, 34,161, 80, 99,148, 82, 98,177,129, 19, +248,121, 51,180,204,108, 22, 22,221, 49,125,255,205,122,227,235,147, 39,177,206,124,183, 74,165,250,183,237,255,156,156,156, 82, +111,111,111, 74,167,211,113,246,105,250,244,233,243,121, 3, 51,246, 89,245, 45, 83,161, 35,237,255,242,229,203,104,235,227,103, +111, 13,112,199, 10, 80,201,252, 75,245,101, 88,250,236,130,202, 7,111,236,120, 23, 8, 5,198, 44,143,195,182, 57, 91, 92,105, +100,117, 13,110,245,110,168,183,111,223, 6, 0, 52,111,222,188,202,255,112,193,156,221,128,130, 8,169, 77, 8, 48,155, 25, 91, + 60, 64,131,104, 1, 13, 80,150,246,204, 31, 0, 72, 66, 66, 2, 0,220, 73, 77, 77, 13, 76, 72, 72, 40,119,154,249,155,205,160, +105, 19, 76, 52, 13,115, 53,230,207,115,174, 85, 67, 92, 92, 28,178,179,179,255,234, 93,201,201,136,137,137,169,188, 78, 79, 79, +175,183,176, 99, 39,240,212,187,253,217, 51,254,113,227,198,161,103,207,158, 54, 1,192, 85,139, 64,131, 52,194,130, 27,249,208, +109,251, 23,124,222, 92,137,240,136,230, 8, 11,150,225,198,182, 27, 22,230, 31,224,103,113, 1,136, 4,206, 73,176, 13,228, 99, +107,119,233, 58,110,207, 95, 12, 67,218,250,186, 45, 4, 50, 25,140, 70, 35,114,115,115, 81,108,188,138,118, 8,175, 53,173,213, + 12, 94, 87,219, 39,182,126, 98, 77,155,233, 70,255, 34,118,253,154,119,179,159,145, 58, 24,183,211,109,176,166,239,141,137,137, +225, 9, 33, 54, 87, 78,125,190,215,214,151,121,161, 80, 88,175, 58,143,143,143,247, 7, 48,230,224,193,131,255,226, 56,206,100, +215,150,132, 2,129,192, 59, 62, 62,126,242,134, 13, 27,246, 56,228,152,115,103, 9, 75,239,148, 72, 69, 34,137, 55, 37, 36,126, +188, 64,226,197, 9, 4, 66,142, 80,224,136,144,229, 5, 2,147,128, 35, 70,157,128,213,123,139, 69,228,155, 99,123,140,137, 73, +147, 56,228, 59,206, 99,121,121,185, 70,175,215, 51, 0,160,211,233,184,143, 62,250,168,146,225, 47, 89,178,228, 31,245,109,239, + 67,135, 14,157,106,251,255,192,129, 3, 41, 13,209,135, 40, 71,218,255,226, 87, 98, 96, 44, 41,193,236,206, 29, 96,239,187,119, + 90, 11, 25, 61, 58, 10, 64, 21,230, 63,122,244,232,104, 0,100,244,232,209,209,235, 70,127,101,177, 44,182,111, 84, 37,189, 51, +152,179, 38, 7,115,214,228, 96,218,138,203,120,125,209, 31, 24,251,207,115,245, 31,232, 10, 10,156, 18, 12, 30, 22,243,183,250, +252,249, 90, 44, 1, 48,211, 52,250,246,233,211, 16, 66, 6,191,101,203, 22,108,217,178, 5, 10,133,162,242,112, 81,224,225, 21, + 10, 5,162,163,163, 43,153,191,253,195,132,132, 4,149, 51, 3, 19,195,176, 22,205,223,100, 49,253, 87,103,254, 44,203, 66,103, +208,185,244,129, 54,139, 65,117,171, 65,122,122, 58,210,211,211,171, 8, 3, 46,125,111,102,213,241,208,122, 93, 47, 33,209,198, +252,199,141, 27,135,229,203,151, 87, 50,127,145, 80,228, 42,243,183, 13,224,181, 29, 78,195,128,124, 84,140,233, 11, 62,109, 54, + 10,110,228,131, 31,211,241,175, 66, 72,155, 13, 97,147, 16, 32, 32,224,161, 74,198,186,210, 92, 24,210,214,131,231,121, 92,188, +120, 17,131, 7, 15,134, 76, 38,171,194,248, 3, 3, 3, 97, 48, 24, 96, 48, 24, 80, 88, 88,136,241,134, 25,248, 38,240,189, 90, +105, 58,105,242, 38,213,210,186,202,184, 27, 74, 89, 33,181, 48,127,167,219, 96,245,239,141,137,137,225,211,211,211,145,150,150, +134,216,216, 88,190,190,223,107,101,254, 96, 24,198,237, 62, 17, 31, 31, 47, 5,240,246,129, 3, 7, 62, 90,180,104,209, 9, 66, +136,220,118, 0,104, 22, 28, 28,236,117,232,208,161,181,241,241,241,131,235,162,243, 85,202, 90,129,128,136, 36, 52,195,251,153, + 76,230, 80,150,227,154,177, 28, 23,193, 18,210, 2, 2, 65, 48, 33, 36, 0, 68,224,199,241, 8,226,105, 46, 64, 99, 48,123,135, +250, 49, 2,170,143,214,169, 58,210,235,245, 76,117,173,255,113, 7, 85, 23,227,110,215,174, 29,218,250,248, 65, 95,116, 23,207, +247,236,229, 50,131,182, 9, 17, 11,183, 44, 6,128, 74,230,111,179, 34,236,216,177, 35,211, 38, 4, 20,104,238,160,215,156,126, + 46, 9, 25, 58, 3, 11,157,129,197,221, 50, 19, 10, 75,140,184,125,207,232, 22,227,179,117, 22, 71,204,255, 81,161, 14, 33, 0, + 70,218, 4,163,209, 88, 31,242,188, 66,161,128,205, 71, 30, 18, 18, 98,175,205,194,133,193,164,138, 38, 92,135, 41,209,225,160, + 71,155, 77, 22,205,223, 68,131, 54, 87,101,254,102,179, 25, 58,157, 14, 90,141,246, 81, 87, 11,191,101, 75, 90,213, 79,178,252, +193,122,223,173, 1,207,158,249,219, 24, 63, 69, 81,144, 74,165,240,246,241,170, 87,134, 71,191,148,192,215,118, 56,122,119,223, + 63, 23, 32, 24, 3,192, 12,157, 14, 0,240,201,186,142,243,185,101,150, 65,126,232,116,152, 47, 46, 4, 74,203, 92, 43, 64, 43, +220,253, 30,111,148, 2, 0,214,175, 95,143, 29, 59,118,224,211, 79, 63,197,201,147, 39, 97, 50,153, 80, 92, 92,108,211,202, 42, +211,135,135,135,195, 0, 64,128,155,143,164,189,212,209,238, 73, 61,132, 70, 82,135, 5,207,101,154,246,150,176,154, 98, 2,220, + 97,254, 0,224,174, 16, 16, 31, 31,223,216,202,252,167,124,255,253,247,151,230,205,155,247,210,198,141, 27,209,174, 93, 59, 0, + 64,203,150, 45,161, 86,171, 37, 11, 23, 46, 60,125,232,208,161, 31,227,227,227,229,181,150, 18,199, 19,112,140,148,101,153, 32, +150, 97,155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84, 32,240, 22, + 50,180,223,205, 51,103, 37, 19, 67,190,112,152,239,156,156,156, 82,157, 78,199,213,100,230,239,222,189,251, 85,154,166, 27,172, + 33,117,239,222,189,193,104, 9,235, 98,220,255,153,242,214, 95,204,182,224, 54,102,119,238,128, 21, 22, 6,237,146,212,106,211, +254,109, 76,191,218,239, 84, 94, 7,119,109,236, 82,230, 43, 12, 44,180,122, 6, 26, 29, 3,117, 5, 3,149,150,113,189, 87,214, + 16,249,111,175,229,219,255,127,227,198, 13,168, 84,170,135, 54, 98,164,164,164, 64, 46,151,195, 22,244, 87,205,215,207,167,164, +164,192,104, 48,212, 71, 0,224,215,173, 91,135,130,194, 66,136, 4, 2,132, 53,110, 92,133,249, 63,251,236,179, 56,120,240,160, +179,131, 19,137,142,142,174, 46, 4, 84,177,100, 56, 27,171, 64,155,104,208, 38, 19,204,102, 26, 12,195, 86, 50,127,147,201, 4, +189, 94,143,138,138, 10,104,181,174, 11, 0,246, 46, 0, 27,220,213,252,183,164,109, 1,120,160,212,202,104,172, 78,109, 16,158, +183, 8, 1,105,105,136,179,104, 80, 46,245,149,234,204, 95, 36, 18, 65, 34,145, 64, 42,149, 66, 42,149,214,187, 77,213,230, 18, +168,105, 94,188, 61,198,166,108, 5,255, 98, 4,238,245,239,133, 96, 12,128,236,229, 85, 96,238,150, 0, 1,126, 16,150,109,194, +174, 47, 78, 3, 2,129, 75,121,169,175, 43, 64, 39,176,140, 41, 75,151, 46, 69, 73, 73, 9,214,174, 93,139,238,221,187, 99,209, +162, 69,232,213,171, 23, 12, 6, 67,117, 13,205, 38, 82, 63,108,198,239, 44,131,118,215, 29, 80,155, 32,225, 50, 29,235, 44,142, +202,190,225,174,107,204,158,249, 87, 50, 27,171, 16,224,162, 59,192,247,194,133, 11, 95,190,243,206, 59, 71,186,118,237,234, 7, + 0, 11, 22, 44, 64, 78, 78, 14, 0,160, 95,191,126,248,229,151, 95, 48,112,224, 64,239,241,227,199,231,102,102,102, 30,120,227, +141, 55,198,159, 61,123,246,190,146, 13, 10, 14,226,110,220,200,101, 50, 21, 7,247,182,105,211, 54, 51,162,165,252,146,192, 87, + 86, 44, 32, 98, 29, 37, 17,233, 41,169,151,150, 22, 10,104,240,102, 1, 39, 53,251,106, 11,203,124, 78, 30, 58,215,167, 81, 96, +216, 47, 14,133, 81, 59,159,255,182,109,219, 94, 31, 51,102,204,247, 54,179,191, 70,163,161,196, 98,113,189, 27,146,205,236,127, +224,192,129, 7,107, 1,176,105,249,145,173,219,194, 88, 82, 2, 93,129,133, 9, 14,182,106,135,174, 90, 1,110,252,113,253, 62, +218, 53, 93,151, 93, 44,114, 41,243,245,101,254,246,140,159,231,121,155,143,191, 18,102,179,185,242, 80,169, 84,208,233,116, 80, + 42,149, 15,109,228,176,205,243,223,183,111, 95,117, 75, 0,159,146,146,130,110,221,186,193,104, 52, 84, 14,116, 41, 41, 41, 46, +153,235,215,124,181, 6,102,179, 25,205,194,195, 97,102,217,218,152,191, 43, 3, 9,169,193,244, 95, 57,117,177, 46, 75,198,125, + 2, 0,109,174,100,254,167, 78,158,130,222, 96,128, 86,171,133, 90,173,134, 74,165,170,162,217,185, 10,155, 27,160, 30,126,127, +148,149,150,161,172,172, 20,165,101, 74,148,150,149,161,172,172, 12,101,165, 22,141,180, 67,199,142, 80, 90,255,119, 85,251, 7, +128,158, 61,123,254,165,245,123,123,195,199,199, 23,190, 62,190,208,106,181,209,245,100,254,110,187, 3,114, 63,157, 2,209,203, +171, 16,140, 1, 16,102,173,130,121,235,116, 32,192, 15, 59,223,141,193,173,157, 55, 49,106,249, 6, 64,248,144,151, 21, 49,222, +130, 44, 92, 6,157, 78, 7,163,209, 8,189, 94,143,172,172, 44, 44, 91,182,172,198,228, 94, 94, 54, 11,202,117,119,152,183,187, + 90,181,125,249, 18, 39,175,235, 35,100,184,218,103,171,208, 73, 75, 75, 35,177,177,177, 54,230,239,182,101, 66, 40, 20, 18,134, + 97,170, 11, 5,112, 53, 22, 96,195,134, 13,215, 98, 99, 99,187,111,220,184,113,240,209,163, 71,125,135, 14, 29,122,210,198,252, +173, 10, 36, 36, 18, 9,127,235,214, 45,209,222,189,123,219, 7, 6, 6,158, 26, 48, 96, 64,110, 77,180, 94,125,229, 85,174,109, + 68, 59,109,191,126,253, 98, 46, 93,250,243, 25,141, 78,219,152,103,204, 12, 40,152, 25, 19,101, 50,153, 76, 6, 13,138, 52,156, +201,168, 45,204, 47, 98,118,237,222,147,212, 40, 56,164,152,166,245, 14,213,247,154,180,255,242,242,114, 33, 0,248,249,249, 61, +182,110, 1,170, 54,237,127,203, 39, 31, 89,164,230,162,187, 85,158,185, 26, 11, 48,122,244,232,232, 53,111,175, 4, 96, 9,248, +219,177, 99,135,194,198,244,109,107, 2, 12,251,225, 37, 0,192,153,229,191,219,226, 3, 30, 22, 42, 27, 99, 65, 65, 65,165,182, +111, 99,250,118,149, 11,173, 86, 11,163,209,104, 55,136, 60,188, 60, 78,157,106,137,253, 48, 51, 12, 46, 93,186,132,179,103,206, +160,123,183,238, 48, 26,141, 48, 24,140, 48, 26, 12,248,241,135, 31, 96, 75,231, 76, 71, 79, 78, 78, 70,167,142,157, 96, 54,155, +113,237,218, 53, 48,102, 26,133, 5,133, 13, 90,166,182,107,235,154, 5,182,181, 11, 28, 91, 0,204, 38, 48,172,197,236,127,226, +196,239,208, 25,116,168,208,106,160, 86,171, 81,174, 82,161,188, 92, 89, 47, 65,204,102, 9,112, 83,251, 7, 0, 28, 57,114, 4, + 90,173, 22, 90,173,198,122,214,162, 81,112, 48, 58,116,236,136, 43,151, 47,227,240,145, 35, 46,211,180,105,255, 66,161, 8, 94, + 94, 94,240,241,241,129,175,143, 15,124,124,188,160, 44, 87, 70, 39, 36, 36,100, 58,213,231,234, 97,234,175, 13,231,115,203, 96, +190,184, 16,101, 56, 6, 50,114, 5,200,128,127, 33,247,211, 41,120,113,249,247,144,138, 40, 64, 36,180, 28,238,112, 29, 55, 93, + 1,133, 47,124,133,160, 77, 47, 64,175,215, 35, 40, 40, 8,229,229,229, 40, 47, 47,199,241,227,199,113,247,238,221, 74, 51,113, +101,250,194, 66,188, 27, 40, 67, 35,175,146,186, 52,224,104,123,166, 26, 27, 27, 27,101,247, 44,170,218,179,104, 23,251, 5, 95, + 7, 3,111,136, 25, 5, 46,107,254, 53,125,111, 90, 90, 26, 73, 79, 79, 39,245,252,222, 42, 66,128, 59,204,223,134,143, 63,254, +248,194, 75, 47,189, 52,126,233,210,165,237,207,159, 63, 63, 64, 38,147, 9, 94,124,241, 69, 34,145, 72,192,113, 28, 25, 57,114, +228,133,153, 51,103,118,235,210,165,203,206,201,147, 39,191, 62,121,242,228, 90,125, 81, 9,211, 18,184, 63, 47, 95, 59,213,165, +107,183,215, 78,157, 60, 57,118,231,238, 95,151,100,159, 60,217,248, 82,206, 21,233,181,194, 92,254,199,149,155,101, 75,147, 63, +237,116, 96,247,238,228, 54,173,219,236,242, 9,243, 62,178, 97,195, 6,214,217, 18, 29, 58,116, 40, 78,157, 58,213, 35, 37, 37, +101,161,209,104, 20, 45, 90,180,232,179,157, 59,119,142, 43, 44, 44,124,232,140,195,169, 58,170,237, 65,240,205, 60, 40,129, 74, +237,223,134,193, 33, 33, 88,129, 43,206,107, 29, 86, 19,255,149,211,151, 16,208,190, 17,134,253,240, 18,118, 76,220,174,176, 73, +111, 54,230,111,211,254, 93,153,101,240,203,210, 30, 13,195, 97, 9,193,229,203,151, 97,107,172,213,205,203, 34,145, 8, 34,145, + 8, 37, 37, 37, 24, 57,114,228,163,168, 39, 34,151,203,249,148,148, 20,244,233,211, 7, 70,147, 9, 6,163, 1, 70,107,112,147, +193,104,113, 3,172, 94,189, 26,137,137,137,142, 6, 19,126,249,242,229, 96, 89, 22,167, 79,159,129, 72,104, 49,219,182,109,219, + 22, 55,243,242, 80, 88, 88,136, 77,155,126,198,184,113,175, 2, 0, 95,205, 18, 80,235, 0,148,154,154, 42, 6,192, 36, 36, 36, +112, 53,105, 64,174, 76, 85,180,105,254, 89, 89, 89,208, 85,232, 43, 5, 48,141, 86, 3,141, 70, 13,141,198, 61, 23,128,189,246, + 63,110,220,184, 74, 11,128,171,130,192,184,113,227,170, 92, 71,200,229,232,208,209, 18, 20,119,229,242,101,220,180, 90, 60,198, +141, 27,231,114,212,126,255,167,251, 67, 34,150, 64, 38,147, 65, 42,149, 66, 34,145,160,168,168,200,105,230,111,167,237, 55,104, + 3, 28,187,108, 29,126, 1, 48, 98,233,255,129, 79,155, 13, 18,151,140,243,185,101, 32, 65,129,184, 94,160,177,104,255, 46,186, + 0,236,250, 31,177, 9, 2,246,215, 14, 97, 48, 0, 2,139,178,247,151,121,223,194,232,205,102, 51,190,249,230, 27, 12, 30,252, + 87, 92,216,193, 73,225, 64,177, 30,237,247,148,163, 71, 72,203, 26, 73,214, 16,229,110,239,242, 84, 56, 72,235, 44,195, 38,245, +176, 40,212,101,141,112, 89,144,120,208,223,107, 21, 2,234, 61, 11, 96,233,210,165,155,102,204,152, 17,114,238,194,133, 56,131, +193,208, 77,161, 56, 36,147, 72, 37, 66,138, 80, 56,116,232,144,111,167, 78,157, 54,196,198,198,254,107,236,216,177, 14,181,245, +204, 67,251,185, 81, 47,141, 58,220,189,123,207, 57, 52, 99, 26,113, 61,231,218, 18, 46, 47,151, 1,192, 75, 65,153,187,182,105, +159, 22, 26, 26,178, 71, 32, 20,255,248,239,121, 73,244, 23,139, 62,119, 88, 75,125,250,244,249,124,232,208,161, 0,128,146,146, + 18, 28, 56,112,192,239,187,239,190, 91, 2, 0,167, 78,157,234,211,185,115,231,125, 79,132, 0, 96, 91,248,231,217, 31, 55, 58, +210,236, 93,153, 18, 72,182,205,217,194,247,154,211, 15,193, 93, 27, 87, 50,253, 74,115,234,197, 34,156, 89,254,187,171,102,171, +134,154,147, 74, 0,240, 29, 59,118,196,197,139, 23,171, 48, 22,149, 74,149, 11,160,181,139,210,252,131,180, 4,220,247,155, 63, +254,240, 35,140, 70, 35, 76,180, 9, 52, 77, 99,249,242,229,117, 45,146,195, 47, 95,190,188,242,130,227, 88, 72,101, 62, 48, 24, +140,184,124,233, 18,132, 34, 17,204, 52, 13, 47,111, 47,108,218,180, 9, 2,129, 0,113,113,113,120,246,217,103,249,178,178,218, + 3,188,150, 47, 95,190, 47, 33, 33,129, 78, 77, 77, 13,181,149, 77,181,117, 0, 92, 50,109,206,153, 51, 7,199,142, 29, 67, 69, + 69, 5, 42,116, 58,104, 53, 26, 43,243,215, 64,171,209,162, 66, 91, 1,157,221,128,239, 76,217, 69, 70, 70,242,217,217,217,149, +218,127, 77,211, 0,157, 93, 4,200, 58, 23,191, 74, 93,216,152,190,205,247,232,202, 42,133,182, 21,254, 0,192,199,203, 7, 82, +153, 20, 90,173, 54,218,230,218,113,131,249, 63,144,249,218, 54, 33, 96,204,210,239,192,111, 5, 26, 77, 74, 69,230,123, 49, 24, +152,244, 19, 32, 18,193, 91, 90, 63, 63,103,117, 65, 0, 0,198, 29, 27,231,224,173,123,232,186,207, 11, 69,191,234, 81,190,248, +175,187,102,179, 25,131, 6, 13, 2, 0,132, 7,202,240,223,212,230,248,116,217,109,124,117,198,224, 72, 35,182,159, 22,135,218, +254,183, 75,155,233,198,152,213, 80,115,235, 27,194,231,255, 32,191,183, 82, 8,104,136,246,247,229,151, 95,126,249,198,164, 55, +246, 62,213, 59,178,143, 86,163, 9, 98, 88,198, 20, 22, 22, 86, 18, 30, 30, 94,164,209,104,206,143, 29, 59,214,233, 65,225,215, +237,191,114, 0, 54,189, 54,225,173,172, 1, 3, 7,110,151,201,100,254, 4, 60, 71, 8, 1,199,241,106,131,174, 92,113,245, 66, +190,214, 91, 34,118,106,156,183, 49,127,192, 18, 72, 93, 61, 80,111,217,178,101,255,122, 34, 4, 0, 43, 83,119, 88, 97, 59,118, +236,112,185,177,158, 89,254, 59, 15, 0, 54, 65,192,142,241, 55, 36, 67,119,187, 35,117,237,218, 21,167, 78,157, 66, 73, 73,165, +137,176, 53, 0,216,152,223,196,137, 19, 31,117,125, 85, 41,163,148,148, 20,254,181,137,175, 97,245,234, 53, 86,159, 57,131, 57, +115,230,212, 57,125,201,197, 21,244, 44,154,211,193,131,142, 54,155,232,184,124,249,242,107, 9, 9, 9,197,169,169,169,130,132, +132,132,202,128, 64,235,180, 64,167, 7, 58,155,198, 60, 96,192,128, 6, 47,187,200,200, 72,222, 94,139,183,143, 1,112, 99, 5, + 64, 2,128,223,180,105,211,125, 90,190,213, 66,224,114,123,222,180,105, 19,113,213, 98,224, 12,234, 50,253,187, 42, 44,140, 93, +182, 14,176, 91,248,103,200, 71,127, 77, 71,214, 53, 84, 69,217, 89, 0, 28,173, 4, 88, 56,160, 16,133, 0,122,125, 26,136,197, +167,219, 33, 4, 64, 73,174, 14,109,218,180,177, 48,141,197,129,120,238,169, 16, 68, 60,151,227,172, 70,236,180,123,211,154,150, +184, 59,222, 52,208,152, 87, 47, 90, 15,233,123, 27, 12,235,214,175,187, 6,224, 90, 67,209,251,241,167,111,243,208, 0, 81,161, + 13, 25,152,103,197,172,135, 81,158, 15,123, 51, 32, 50,122,244,232,168, 29,203, 31,203,189, 0, 8, 0,254,169,167,158,194,158, + 61,123,140, 86,166,207, 1,240,122, 64,150,135,122,195, 22, 36,152,152, 56,141,183,106,254,143, 36,111,115,230,204,105, 89,147, + 89,210,110, 26,161, 43,218, 14,121,192,117, 92,153,159,250, 46,251, 91,219,170,124,174, 50,113, 71,107,251, 55, 4,234,227, 18, +152, 59,119, 46,110,220,184,209, 96,121,113,102,121, 95, 87,113,230,131,114,156,129, 37, 48,116,112,172, 12,191,157,104,135, 48, + 47, 31,252,153,125, 15,237,157,100,254, 78,180,191,199,117, 57, 92,242,128,222,245, 44,207,238, 28,154, 54, 48,189,228,135,149, +241,135,190, 27, 96,117, 11,131, 27,150,132, 7, 46, 4,140, 28, 57, 82,250,132, 53, 64,183, 52,251,134,250,237,212,212, 84,219, + 10, 53, 76, 66, 66, 66,125,167, 50,121,208,240,204,191, 94,117,145,148,148,212, 32,117,153,154,154, 42, 76, 24,152,240,192,219, +197,145, 52, 3,142,164,229, 60,246,125,214,211, 50, 61,120,228,141,208,221,125,132, 61,240,192, 3, 15, 60,240,192,131, 39, 23, +148,167, 8, 60,240,192, 3, 15, 60,240,192, 35, 0,120,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, 15, + 60,240, 8, 0, 30,120,224,129, 7, 30,120,224, 1, 0,156, 4, 80, 98, 61, 63,145,168, 50, 11,224,220,185,115,110, 71,166,214, + 20, 76,232,161,231,161,231,161,231,161,231, 36,189, 58,167,137, 62, 6,244, 60,245,235,161, 87,133,249,159, 61,123,118, 24, 96, +217, 96,146, 16, 98,124,220,190,215, 99, 1,240,192, 3, 15,224,239,239, 79,249,251,251, 19,127,127,127, 17, 0,193,227,150, 63, +219,190,243,118,251,207,215, 23, 53,173,143,239,193, 99,132,255,251,191,255,139,122,194, 63,161, 15, 0,219,178,195,162, 39,245, + 35, 60, 2,192,223, 28,245,216,110,221,101, 12, 27, 54, 44,202, 58,232, 86, 30,214,123,127, 75,122,143, 57, 72,203,176, 48, 2, + 0,106,181,154, 83,171,213,188, 90,173, 54, 3, 96,221, 33,246,246,115, 93, 11,166,140,232, 58, 26, 0,166,140,232,250,195,219, +207,117, 93, 3, 0,115,198, 60, 69,230,188, 28, 41,122,123,120, 23,183,214, 20,177, 95,138, 54, 45, 45,173,202,230, 59,245, 97, +254,118,237,190, 33,215,218,175, 47,205,134,166,247,196, 50,255, 61,123,246, 40,254, 6,159,194,160,225, 86,116,172, 21, 77,130, + 37,164,109,227, 80,170,133,188, 25, 9, 11, 8, 22,120, 75, 68, 13,246,123,194,191, 73,155,162, 0,200, 96, 49,199,112,240,160, +138, 0,224,196,222, 42, 38, 0,146,250,254, 84, 70, 70, 6,146,147,147,171, 44,255, 55,107,214, 44, 91, 71, 39,238,208,227, 54, + 7, 86,173,232, 87, 50, 30, 23,122,143,125,213, 71,120,203,248,136, 86,114, 0, 64, 17,205, 76,104, 44, 22,254,100,123,120, 69, + 83, 33, 41, 42, 45,165,157, 33, 52,121,120,151, 28,150,229,195,159,238,223,200,175,125,251, 1,251, 37, 18,234,214,180,164, 62, +255,254, 15,185,136,123,106,253,255,137,132,228, 87,128, 92, 2,208,217,213, 76, 86, 95,138,182,158,203,205, 86, 97,254,118,109, +223,221, 65,154,184,120,255, 97,211,123, 98,153, 63,199,113, 32,132, 96,240,224,193,252,145, 35, 71,136,139,117, 44, 6, 96,110, +136,252, 4, 5, 5, 77, 81, 42,149, 95,187,249,186, 4,128,209,206, 18,208,160, 24,208,173, 7,121, 45, 60, 66,168,106,209, 72, + 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195,217,250,254,134,179, 2, 64, 8,128, 72, 0, +217,176, 4, 61, 60, 78,240, 3, 48, 20,192, 24, 0,219, 0, 28, 0,160,105, 0,186, 63, 3,120,181,129, 24,236,163,147,140, 40, +135, 70,158, 62,214, 14, 21, 10,160,216,221,129,119,230,204,153,104,209,162,197,125,219,133, 38, 39, 39, 71,231,231,231, 43, 86, +174, 92,233,202, 32,204,175,159,238,141,248,129,247,111, 46,195,109, 14,196,134,255,210,152,180, 74,247,200,232, 45, 95,190, 60, +234,195, 15, 63, 84,196,197,197,225,231,159,127, 38, 0,240,206, 59,239, 68,173, 93,187, 86,209,162, 69, 11,112, 28, 7,131,193, +128,168,168, 40,108,221,186,213, 33,205,117,203, 63,139,106,255,225, 22, 69, 70,175,102,209,243,179,211, 51, 1, 96,205,194, 53, + 81, 87,231, 51, 10,182,133, 31, 52,156, 55,202, 13,126, 40,246, 63, 21,125,242,198, 39,153,142,232,181,106, 22,214,184,133, 88, +118,119,250,180,137,166, 48,153, 88,172, 81, 26,200,242,239, 54,254,244,209,212,215, 16, 40,147,241, 70, 51,203,127,178,250, 59, + 83, 81,105, 41,105,220, 56, 88, 88, 84, 84, 86,107, 35, 57,179,237,229,182, 59,118,222, 14, 24,240,116, 72,114,207,222, 65,162, +245,235,175,203, 67, 26,201, 74, 63,127,239, 68,242,140,151,122,176, 79,247,111,148,149,115, 77,155, 63, 41,190,245,200,111,246, + 95,172, 15, 83,172,175, 38,197,215,100,241,170,167, 16, 80,219, 59,238,230,181,161,233, 61,177,204,127,214,172, 89, 24, 60,120, + 48,255,223,255,254,215, 29, 82, 52, 44,102,119,166, 1,178, 85, 20, 20, 20, 52, 70,169, 84,110,115,227, 93,127,171,210, 25, 8, +224,110,124,124,124, 0,128, 41,214,107, 27,238, 1,248,117,195,134, 13,185,206, 18,253, 98,237, 23, 20, 93,106, 18,209, 38,163, +180, 28,102,169, 72, 36, 20,106,140, 82, 74, 44, 54,112, 2, 63,111,134,150,153,205,194,162, 59,166,239,191, 89,111,124,125,242, + 36,182, 62,109,199, 25, 23, 64,115, 0, 63, 0,136,177,158,155, 63, 70,109, 42, 24,192, 38, 0,207, 3, 56, 14, 96,132,245, 58, +184, 1,104,191, 2, 39,252,165, 15,211,196,254,128,208, 15,192, 85, 0, 17,238,104, 35, 54, 19,186, 61,243,159, 53,107,150,194, + 78,243,175,124,230,140,185,221,150,198,158, 89, 83,175,148,131,122,165,188,242,218,246,236, 81,208, 3,128, 19, 39, 78, 40,164, + 82, 41,178,178,178,238, 19,182,242,243,243, 73, 65, 65, 1,233,215,175, 95,244,238,221,187,157, 42,195,198, 39, 46, 41,120,169, + 8,221, 74,196, 85,180, 97, 66,241, 88,147,255, 6,249,161, 32,142,200, 71, 92,140,102,238,188,224,208,108, 26,213, 74,206,183, + 16,203,238,190,255,238, 4, 83, 51, 31,177, 88,125,233, 24,241, 42,190,128, 25,131,218,162,105,128, 12,197,103,142,146,123,167, +143, 81,179,166, 76,164,163, 90,201,249, 14, 94,190,230,186, 52,152, 70,141,196, 67,196, 98, 74,122,252,248,221,153,167, 78,222, +233, 24,214,172,149, 57,160, 81, 51,226,235, 11,175, 86, 17, 94, 17, 65, 65,146, 54, 28,207,155,118,157, 44,214, 61,194, 54,204, +219, 51,123,219, 81, 67, 31,229,157,165, 85,237, 92,253,168, 41,221,195,162,247,196, 50,255,221,187,119, 43, 8, 33,160, 40, 10, +217,217,217, 56,122,244,168, 91,180, 88,150,189, 96,181, 0, 52, 68, 60,139, 76,169, 84,110, 11, 10, 10,122,217,141,119,205,214, +250, 50,197,199,199,135, 1, 88,113,240,224,193,127,103,100,100,188,111, 59, 14, 28, 56,176, 92,161, 80,228,196,199,199,207,119, +134,224,172,185,179,132,165,119, 74,188, 12,188, 41,128, 23,146, 80, 94, 34,105,204,137,196,141, 57, 66,133,114, 68, 24,194, 8, + 4, 65, 28, 71,252,117,132,245, 97,196,148,236,155, 99,123,132,210, 23, 67, 31,168, 0,240, 5,128,131, 0,102, 88,207, 95,212, +163,176, 3, 1, 44, 0,176,219, 90,112,187,173,215,129,110,210, 59, 2, 96, 15,128, 4, 0,107, 1,252,195, 74,243, 72, 61, 27, +133,191,245,236,221, 0, 26, 54,172, 26,246, 2,235,249,113,195, 83, 0,142, 1,104,108, 21,158, 94,115,229,229,140,140, 12,133, +189,217,127,214,172, 89,138,228,228,228,232,228,228,228,104,123, 33, 32, 57, 57, 57, 58, 35, 35, 67,225, 12, 61,123, 51, 61,245, + 74, 57,174,237,153,136,107,123, 38, 86, 97,218,220,230, 64,184, 75,207, 42,228, 16,119,232,165,164,164, 68, 29, 63,126, 28, 19, + 38, 76, 64,126,126, 62, 18, 18, 18,162,106, 74, 35,149, 74, 21, 77,154, 52,113, 88,126,169, 41, 41, 81, 77,142,255,129,130, 9, + 3, 32,206, 87,227,235, 5,159, 71, 85, 87,142, 83, 82, 82,163, 68,198, 22,138,160, 38, 6,135,204,127,202,228, 87,232, 79,102, + 78,228,197,183,206,136, 3,239, 93, 36, 23,239,106, 16, 30,226,141,167, 59,133,161,169,234, 42,110,104, 13, 16,114, 60, 2,136, + 64,244,207,183, 38,240,211,223,121,243,106, 84, 43,121,173, 76,167, 92,165, 13,234,211,199, 39,185,107,191,231,205,190, 65,173, + 37, 62, 1,161,156,204,199,219, 20,212, 40,216, 24, 18,222, 92, 88,174,212, 74, 52,106, 6,229,106,147,211,131,144,213,207,239, +144,113, 58, 25, 15,112,159,230, 95,147, 80,238,130, 16, 64,106, 56, 87, 63,106, 74,231, 20, 61,126, 75,224,125,135,139,244,158, + 56, 80, 20,197,239,221,187, 87,193,113, 28,222,123,239, 61, 16, 66,112,244,232, 81, 88,182,222,229,136, 27,244, 64,211,244, 89, +171, 5,160,190,110,108, 37, 0, 40,149,202,173, 65, 65, 65,209,238,240, 79,154,166,133, 0,190, 62,112,224, 64,252,162, 69,139, +238, 16, 66,196,182, 3,128, 40, 56, 56,152, 28, 58,116,104, 94,124,124,252,116, 71, 4, 5, 68, 36,161, 25,222,207,100, 50,135, +178, 28,215,140,229,184, 8,150,144, 22, 16, 8,130, 9, 33, 1, 32, 2, 63,142, 71, 16, 79,115, 1, 26,131,217, 59,212,143, 17, + 80,125,180, 15, 76, 0, 8,183,106,252,159,194,178,219,231,167,214,235,112, 55,126,107, 34,128,124,107, 3,159, 11, 32,200,122, + 38,214,251,174,238,181,251, 47, 0,215, 1,172,177,154,131, 36,214, 6,241,149,245,126,125,246, 95, 30, 12,139,171, 99, 72, 3, +245,129, 55, 1,204,183,158, 31, 55,116, 6,176, 29,192,179, 86, 75, 74,103,119, 9,217,152,191, 61,211,183, 23, 2, 92,110,156, + 86,230,111, 67,117, 33,192, 29,122,213, 6, 88,226, 42,189,195,135, 15,131,166,105,244,238,221, 59,186, 67,135, 14,200,203,203, +171,252, 62,142,227, 32,151,203,249,121,243,230, 41,142, 31, 63,142,145, 35, 71, 58, 28, 80,140, 89,167, 64,209, 12, 84,189,229, +209,166, 14,193,184,190,238,240, 95, 76,139,227, 49, 77,190,142, 63, 60, 47, 88,113,243,184, 63,134,189,113,205,241, 0, 69, 9, + 42, 74, 46,102,113, 69, 42, 35,202, 42,104, 62,166, 71, 11,222, 95, 38,198, 29,149, 14, 37,106, 3,226,122,182,224, 41, 66,248, +223,127,221, 7,245,145, 19,252,153,109,187,110,213, 69, 46,235,108,211,105, 33,161,126,173,155,182,136, 96,188,100, 92,235,193, +207,199,249,180,234,157,240, 66,227,118, 47, 14, 11,106, 26,217, 93, 89,209, 56,198, 76,155,205, 55,114,117,126, 78, 50,127,222, +217, 45,104,211,210,210, 20, 14,102, 6,212,248,204, 9,151,156,103,118,192, 67,212,252,121,158,135,217,252,151,203,126,224,192, +129,182,254,226, 46,227, 50,139, 68, 34, 51,199,113,199,173, 90,120,125,132,128,208, 74, 73, 64,169, 84, 4, 5, 5, 37,184,240, +110,185, 74,165,146, 28, 62,124,248,181, 3, 7, 14, 60,255,253,247,223,151,205,155, 55,175,197,198,141, 27,209,174, 93, 59, 0, + 64,203,150, 45,161, 86,171,201,194,133, 11,139, 15, 29, 58,244,121,124,124,252,192, 58, 41,114,140,148,101,153, 32,150, 97,155, +153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84, 32,240, 22, 50,180,223, +205, 51,103, 37, 19, 67,190,112,187, 61, 59, 18, 0,158,179,106,135,246, 56,102,189,239, 10,198, 3,120, 15,128,220,202, 8,255, + 0, 80,110, 61,207,183,222,127,207,154,206, 25,120,193,226,107,137,183, 94,155,236, 14, 88,239, 79,193,253, 91,249, 58,139, 87, + 0,124,103, 61,215, 23,111, 0,152,102, 45,179,105,214,235,199, 5,109, 96, 9,154,220, 5, 32, 17,192, 84, 0, 81,158, 97,171, +118, 20, 22, 22, 42,250,246,237,139,169, 83,167,102,246,237,219, 23, 39, 78,156,192,218,181,107,163, 26, 55,110,172,160, 40, 10, +121,121,121,164,180,180,148, 76,159, 62, 61,250,200,145, 35,138,201,147, 39,215,217, 57,251,223,188,163, 40,234,219, 17, 9, 83, +167,102,254, 25,198, 70,119, 86, 7, 41, 82,215,166, 70, 89,164, 19, 96, 77,222, 27,100, 83,105, 12, 25, 60,189, 48,250,104,154, + 92, 17,253,244,167,181,214, 79, 1,205,172,248,250,235,141, 65, 91, 47, 20,222,222,120, 38, 95,181,238,248, 13,221,205, 34, 35, + 79,241, 20,140,122, 22, 37, 37, 52,178,243,203,217, 29,121,133,218,221,119,138, 84,191,220, 42,184,114,172,168,120,248,109,147, +249,179,218,104,250, 5,134, 55, 51, 84,148, 55,237, 20,249, 12, 69,147,150,131, 11,175,108, 55, 4, 6,121,203, 90,117,236, 81, +194, 51, 37, 23,136,192, 47,132,227, 56,193,189,123, 6,103,172,120,188, 45,226,223,142, 17, 87, 55,131,219, 95,195,154,158,119, + 66,195,174,212,244,109,135, 51,233, 61,120,176,168,168,168, 80, 0,128, 80, 40,196,236,217,179,145,157,157, 13, 55,253,254,246, + 48, 1, 48,153, 76, 38, 83, 97, 97, 97, 6,234, 23, 16,168,173, 98, 14, 80, 42, 83,131,130,130, 70, 57,249,174,212,104, 52,134, +207,153, 51, 39,249,157,119,222,209,119,237,218, 85, 2, 0, 11, 22, 44, 64, 78,142,101, 55,202,126,253,250,129,227, 56, 12, 28, + 56, 80, 50,126,252,120,237,149, 43, 87, 14,189,241,198, 27,125,188,188,106,102, 77, 28,199, 51,153, 7, 15,238,205,203,187, 49, +158, 53,179,141, 4, 34,153, 73, 64,164, 58, 74, 34,214, 83, 82, 47, 45, 45,242,170, 0, 37, 81,115, 82,214,172, 85,151,249, 40, +118,158, 27,197,158, 58,235,118, 0,183, 35, 1, 96, 56,128, 67,213,238, 29,178,222,119, 22, 2, 0, 31, 1,136, 3, 80, 86, 75, +154, 50,235,243,143,224,156, 95,103, 60,128,253, 0,212,181, 60, 87, 91,159,143,119,163, 76,158,129, 37,134, 96,153,245,252, 76, + 61, 26, 87,140,213,106,210,207,154,159,126,214,235, 24, 23,233, 4, 2, 8,112,226,112,213,149,210, 31,150, 85,172,108, 65, 72, +183,172,150, 30,183,226, 60,170,107,252,213, 45, 2,174,130,219, 28,136,182, 35,127,168,188,110, 59,242,135,251,162,248, 93,165, + 87,141,153,240,174,208, 91,189,122, 53,159,157,157,192,140, 1,163, 0, 0, 32, 0, 73, 68, 65, 84,141,211,167, 79,163, 89,179, +102,252,111,191,253, 6,141, 70,131,203,151, 47,223,167,209,126,244,209, 71,153,157, 58,117,138,222,178,101, 75,173,244,190, 89, +189,154,111,158,125, 17,161,167,115,160,104, 54,146,239,122,149, 81, 80, 26, 51,216,203, 21,247,165,125,255,163,183, 50, 91, 68, +158,142,190,245,199, 43,181,106,207,215, 11, 10, 62, 40,160,153, 21, 37,165, 6, 57,109, 96, 3,115,238,104,124,118, 95, 41, 44, + 51,181,236,142, 78,161, 65, 0,128,221,231,238, 9,115,139, 42,252, 0, 4, 22,209,198, 78,183, 77,230,216,220,194,194, 15,106, +163, 57,228,133, 56,170,195,224, 37, 93, 25,221, 31,249, 45, 58, 14,149,137, 68, 44,125,253,143, 12, 85, 97,254,229,123,197,249, +191,231,107,148,133, 0, 69, 17,165,150,246,159, 18,215,211, 81,187, 33,177,177,177,213,153,113,117,179,186,253, 53,172,233, 31, + 86, 52,190, 7, 13,136,193,131, 7,243,135, 15, 31, 6,183, 57, 0, 60,207,227,243,207, 63,199,145, 35, 71,108,130,154,219,117, + 80, 94, 94,110, 34,132, 12, 58,117,234,148, 49, 60, 60,124, 88, 61,173, 58, 1,128,101, 54,128,245, 60, 17, 0, 23, 20, 20,228, +140,162,102,108,220,184,177,122,223,190,125,111,110,220,184,209,255,232,209,163,226,161, 67,135,170,109,204, 31,176,108,119, 47, +145, 72,112,235,214, 45,106,239,222,189,126,129,129,129,119, 7, 12, 24,144,203,113, 53, 79, 86,107, 27,209, 78,219,175, 95,191, +152, 75,151,254,124, 70,163,211, 54,230, 25, 51, 3, 10,102,198, 68,153, 76, 38,147, 65,131, 34, 13,103, 50,106, 11,243,139,152, + 93,187,247, 36, 53, 10, 14, 41,166,105,189,219,179, 16,168, 26, 58, 6,101, 61,154,194,226, 23, 62,108,119,143,178, 94, 55,182, + 62,183,221,171,171,131,206,128, 37, 64,239,102, 53, 58,213,143,155,214,116, 51, 28,208,163, 0,140, 5,240,189, 3,122,223, 91, +211, 81, 78,208,179, 29,173, 96,137,115,248, 24,150,153, 4, 31, 91,175, 91, 85, 75,231, 12,189,241, 0,222,177, 50, 89,131,245, +158,193,122,253,142,245,185, 51,244,226, 97,137,115,112,246,136,119, 34,127,159, 1,248, 15,128, 81,214, 50,167, 0, 72, 1,156, +176, 90,101,250, 2, 72,178, 62,175, 43,127, 24, 54,108,216,125,190,126, 91, 16, 96,245,216,128, 97,195,134, 57, 20, 6,134, 13, + 27, 22, 93,221, 55,223,118,228, 15,247, 49,127,234,149,114,184, 75,207,166,101,186, 74,239,220,185,115,104,209,162, 5,238,221, +187, 71, 10, 10, 10,200,221,187,119, 73,255,254,253,239, 11, 6,172, 52, 83,121,121, 41,164, 82,105,173,244,228,231,206, 65,213, +162, 9,122,220, 59, 65,162, 11,246,144,151,238,110, 38,103,125,138,163,217, 44,117,141, 76, 62, 63,135,134, 68, 90,183,178,115, +189,160, 96, 78, 1,205,196, 20,208,204,138,219,180,249,243,115, 55, 75, 66,244, 12, 3,181,209, 98, 28,187, 84, 82,130,155, 70, +122,195,109,147,121,205,109,154,249, 34,183,176, 48, 29,117, 76,157,109, 42,239, 48, 39,160,105,191,208,210,252, 3, 90,134, 49, +149, 23, 22, 73,155, 93, 56,113,202,255,242,185,243,109,242,110,177, 61,111,223,188, 13,177, 72, 24,218, 57,204,123,188, 74,107, +110,227,168, 62,210,210,210, 72,108,108,172, 83, 66, 97,108,108,108,116, 90, 90,154,203,140,194, 62, 16,240,113,158,161,243,119, +198,144, 33,131,249,204,204,204,202, 24,135,253,243,124,193,243, 60, 6, 15, 30, 92, 31,211, 63,172, 76, 58, 26, 0,158,126,250, +105,125, 53,193,209, 45,121, 34, 40, 40,104,130,157,114,106, 82, 42,149,187,149, 74,229,186, 58,222,177,165,229, 0, 84,132,133, +133, 93,120,233,165,151, 86, 47, 93,186,212,235,252,249,243,254, 50,153, 12, 47,190,248, 34, 36, 18, 9, 56,142,195,200,145, 35, + 43,102,206,156, 25,208,165, 75,151, 43,147, 39, 79,238, 60,121,242,228, 50,163,177,230,133, 3, 19,166, 37,112,127, 94,190,118, +170, 75,215,110,175,157, 58,121,114,236,206,221,191, 46,201, 62,121,178,241,165,156, 43,210,107,133,185,252,143, 43, 55,203,150, + 38,127,218,233,192,238,221,201,109, 90,183,217,229, 19,230,125,100,195,134, 13,110, 79, 7, 20,214,160,173, 71, 2, 24, 0, 96, + 17,128,233,214,193,210,187,154,217,238, 7, 88,252,236,159,192,226, 18,200,174, 67,192,120,202,170,253, 58, 99,142, 63,110,181, + 46, 80,117,208, 11, 1,208, 18,192,105, 7, 52, 79, 91,211,133,162,246,169,139, 20, 44,129,121,129, 86,198,249, 18, 44, 83,255, +114,172,180,115,172,215, 27, 97,241,147,111,128,197,117, 65, 59,160,247, 10,128,111, 0,116, 0, 80, 84, 45,159,119, 97, 9, 90, +188, 98, 77,187,217, 1,189,247, 96,153,221,160,119,162,252,188, 0,236, 3,240,147,131,250,120, 25,192,191,173,231,179,118,249, + 19, 89,235, 50, 13,192, 42, 0,139,173,207,239,214,246,131, 25, 25, 25,153, 0,144,159,159,175,176, 69,251, 87,215,250,243,243, +243, 21,246,105,235,130, 45,205,134,255,210,149,209,249,213,181,244, 13,255,165,241, 40,232,101,101,101, 97,208,160, 65,184,114, +229,202, 95, 76, 92, 46,143,222,178,101,139,162, 85,171, 86,209, 28,199, 41, 90,182,108,201,219,166, 1,238,218,181, 11,145,145, +145,209,123,247,238,173,145, 94,251,172, 44,252, 28, 28, 90,165,172, 58, 38, 14,135,238,211,219,192,179,161,224, 57, 96, 90,203, +239,248, 10,206, 7, 74,131, 31,148, 57, 65,232, 62,104,103,244,229, 95,234, 54,179, 95, 47, 40,216, 10, 96,107,235, 22, 77,219, + 3,248,135,137,229,144,126, 33, 15,131,194, 44,238, 78,194,243, 90, 45,195, 44, 42, 46, 46,190,231, 4, 51,253,148,231,121,239, +156, 43,202,215, 84,167,183, 52, 42,190,171, 68,241, 61, 45,132,194, 50,239,138,114, 30, 42, 13,203,135,134,136, 3,132, 28,198, + 24, 76,236,207,139,222,123, 58,224,147, 47,142,171, 28, 8, 1,153, 78, 12,216,164,154,187,192, 53, 12,181, 90, 94, 14,196,185, +250,166,205, 26,230, 40, 42,223, 62, 29,113,150, 30,137, 43, 71, 61,233, 61, 9,224, 51,167, 93, 4,210, 45,147,177,246, 95, 96, +176, 78, 97,233, 99, 46,206,249,175,181,109, 8, 4,130, 16,161, 80, 88,124,252,248,241,111,159,126,250,233,250,148, 89, 11,165, + 82,185,198, 42, 88,188,162, 84, 42, 55,219,206,117,188,179, 9, 22,151, 41,111, 29,187, 43,150, 46, 93, 58,125,198,140, 25, 77, +207, 93,184, 48,212, 96, 48,248, 42, 20,135,136, 68, 42, 1, 69, 40, 28, 58,116, 72,212,169, 83,167,179,177,177,177, 35,199,142, + 29, 91,225, 40, 67,153,135,246,115,163, 94, 26,117,184,123,247,158,115,104,198, 52,226,122,206,181, 37, 92, 94, 46, 3,128,151, +130, 50,119,109,211, 62, 45, 52, 52,100,143, 64, 40,254,241,223,243,146,232, 47, 22,125,238,118, 65,214, 36, 0,252,195, 42,225, +188, 0,224, 50, 0,159, 26,222,219, 99,213,216, 99, 96,153, 71, 30, 95,135,249,191,173,181,192,156, 17, 0,202,172,233, 5,117, +208,139, 2,112,205, 73,122,215,172,233,127,169,131,222, 20, 0,147, 0, 92, 4, 48,211,250, 93,246,180, 21, 0,242, 96,241,223, +239, 6,176, 30,150, 25, 7,181,209,155,104, 45,143, 30, 86, 43, 66, 77,249,212, 88,159,167, 88,133,128,245,117,208,251,222,218, +208,188,156, 28,188,190,119, 80,126,159, 89, 45, 27,251,173, 66, 13,170,209,254, 13, 64, 39,107, 93,228, 88, 5, 41,135,166, 93, +235, 60,127, 69, 3, 45, 4, 68, 38,173,210,241,147, 86,233,106, 88,184,167, 28,143,138,222,159,127,254, 73,254,252,243,207, 42, +247,126,250,233,167, 76, 0,100,243,230,205, 0, 64,110,221,170, 26, 83, 87, 27,243, 7,128,230,127,254, 73,128,170,244,222, 94, + 50,203,194, 28,151, 89,243, 84, 61, 68,239, 23, 23, 70, 97,150,207,131, 16, 16, 84,160,146,249, 91,185,250, 61,169, 84,234,148, +217,144,231,121, 66, 8, 89, 48, 39,174,179, 87, 88,179,150,163, 56,120,181, 45,200, 47, 18,152,141, 42,190,113,168, 15,241,241, + 22, 17,198,204,161, 92, 69, 51, 68, 70,100,106, 45,211,166, 14,133,160,182, 54, 91,253,255, 71,201, 0,237,221, 17,206,204,219, + 39, 15,153,222, 99,207,252,185,205,129,216,127,193, 50, 69,127,189,130,198,207,199,105, 91, 76, 6,105,168,250, 97, 89,182, 12, + 0,122,245,234, 85,175, 5,129,108,204,223,138, 82,235,217, 81,223, 72,180, 27, 79,205, 0, 10, 0,224,203, 47,191,124,249,141, + 73,111, 12,123,170,119,228, 24,173, 70, 19,194,176,140, 49, 44, 44,172, 48, 60, 60, 60, 87,163,209,108, 27, 59,118,108,169,179, +249,250,117,251,175, 28,128, 77,175, 77,120, 43,107,192,192,129,219,101, 50,153, 63, 1,207, 89,102, 78,240,106,131,174, 92,113, +245, 66,190,214, 91, 34,174, 87, 64,107,117, 1,128,133, 37, 72,205, 25, 63,252, 41,235,193,162,246,229, 69, 89, 88, 34,234,157, +157,175,169,128,101, 33,159,186,232,237,128, 37,104,205, 25,188,230, 68,254,190, 6,240,173,163,177, 31,192,187,118,239,212, 69, +239, 7,171,197,192, 17,242,172,154,189, 51,249,115,101,190,235,215, 14,232, 61,235, 4, 61,155,181, 97,189,181,108,156, 49, 49, +145, 97,195,134, 69, 85,143,250, 31, 54,108, 88,180, 51,154,122,109,244,236, 86,234,123,220,232, 61,246,184, 81,120,215, 68, 53, +107,182,254,157, 79, 83, 38,217,238,209, 34,234, 39,163,158,219, 87,148,159,175,117,170,208, 8,225,255, 61,165, 31,249,248,235, +223,231,236, 90, 21,186,237,196,201,187, 83, 67,252,185, 23,169, 32,191, 0,158, 7, 8,225, 77, 38,134, 43,226,128, 82,218,196, + 5, 20,222, 53,184,228,143,180,154,249, 21,213,174, 31,151, 34,244,172, 4,232, 38,158, 91,172,125,208,223,200, 1,104, 34,149, + 74,239,246,234,213,235,217, 51,103,206,212,155,160, 82,169, 60, 24, 20, 20, 52, 73,169, 84,174,119,242, 21,129, 53, 31,149,227, +233,186,245,235, 50, 0,100, 52,212, 71,254,248,211,183,121, 86, 94,241, 64, 80,147, 0, 96,116,131, 14, 95, 71, 37,153, 60,244, +254,182,244,170,192,202, 72, 73,181,123,110, 55,206,199,157,222,147, 0,165, 94,255, 38,224,101, 6, 16,194,129, 47, 52, 26,233, +141, 69, 69, 37,231,225,194, 42,106, 31,127,253, 59,191,253,179, 17,228,133,233,251,178, 0,100,197,246,109,255,143,160, 32,201, + 92,161,128,240,119,203,140, 87,239,210,204, 6,153,136,146,202,132, 2,129,153,225,164,174,228, 47, 45, 45, 45, 51, 54, 54,214, +182, 15,128,205, 61,224, 58,103,173,238,235,183, 51,253,215, 35, 14,192,179, 18,160, 27,160, 94, 41, 7, 33, 4, 47,142,158, 82, +227, 24,178, 99,123,106, 67,125,107, 17, 0,210, 16,204,223, 78, 8, 88,239, 66,114,153,117, 76,165,159,212,186, 18,214,208, 16, + 27,114,142,172,135,222,223,155,158, 7,143,187, 0,160, 84,242, 74,165,114, 74,125,233,188,244,254, 62, 30, 0, 94, 27,220,137, +252,120,228,210,231, 6,126,218,170,233,227,142,119,162,117, 36, 34, 72, 36,108, 4, 66,244, 62, 50, 97, 73,151, 14,126, 57,233, +251, 93,163,109, 13,244,227,221, 9,248,123,192, 26,180,199, 2,224,198, 55,166,166,166,240, 9, 9, 83,201,142,237,169,127,247, +238,229,111, 21,164, 37,110, 42,206,143,190,178,220,221, 71,216, 3, 15, 60,120, 2, 37,126, 1,224, 37, 33,224, 56, 30, 32, 4, + 21, 6, 79,247,247,192,131,255,217,241,192, 83, 4, 30,120,240,191, 3,134, 5, 52,250,191,245,178,243, 30,120,224,129,147,160, + 60, 69,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, 15, 60,240, 8, 0, 30,120,224,129, 7, 30,120,224, +193,223, 17, 85, 98, 0,206,157, 59,231,118, 52,106, 77,193,132, 53,209,123,225,153,200,168, 46,221,218, 40,154, 52, 11,143,214, + 26,116,138,195,138,172,232,140, 67,231, 51,221,165,215,181,239,240,168, 30,221,250, 42,238, 21, 22,194, 91,230,141,219, 5,185, +209,217, 39,246,184, 77,175,161,191, 55,113, 60, 21,213,175,111, 43,133,204, 91, 0,161,128, 2,145, 18,188, 56,238, 18,113,151, + 94,194,255,203,138,122,170,239, 83, 10,127, 31, 1, 32, 4, 98,251,214, 60,199,233, 81,125,175,135,222, 99, 75,175,206,169,102, +143,251,247,182,234,245, 50,239,199,229, 62,208,252,157,253,232,150,219, 3,105,207, 37, 45,239,187,247,121,163, 66,183,233,253, +163,244,254, 13, 87, 61,237,249,161,208, 19,162,134, 41,178, 79,226,247,186, 44, 0,212,134,149, 81,104, 11,203,122,248, 44,128, +220,153,153,184,233,236, 15, 12, 31,216, 42,138,128, 67, 72, 64, 16,178, 14,159, 81,124,152, 56, 17, 3,134, 14, 0,163,211, 43, + 58,117, 24, 12,142,131, 98,198, 91, 79, 71,247,236,217, 13,215,175,223,130, 90,165,195,234,245, 71, 50,107,163,215,123,208,171, + 81, 60, 8, 90,182,105,165, 72,120,127, 49,222,124,245, 57,252,240,159,175, 0, 72,177,231,124, 1, 40, 10,138,149, 11,230, 33, + 39,231, 42,228,242,150,144,200,132,184, 83,144, 19, 13,125,205, 89,158,251, 92,119, 94, 44, 22, 67, 38,147, 33, 55, 55, 23, 77, + 67,253,208, 72,232,131,166, 45, 2, 16, 40,243,135, 55, 97, 65, 81, 20,120,142,133, 94, 34,132,250,158, 26, 99,254,147,225,176, +162,150,207,233,198,251,202,212,240, 11, 16,195,199, 91, 8,177,140,130, 80, 0, 80, 98, 33, 50,119, 69,242,102, 94,128, 97,163, + 78, 56, 93,225, 93, 95, 90, 25, 21, 30, 30,142,102,173,155, 41, 12, 70, 19, 40,137, 12, 48, 3,211,146, 79, 69, 25,244, 58,124, +247, 73, 84,230, 35, 20, 36,255, 86,243,152,159,112,184, 90, 23, 78,167,143,253,112,174, 55,128,167, 26,203,188,254, 93, 88, 88, +216, 65, 36,149,128,243,242, 90, 6, 96,109,218,178,164,138,199,165, 0, 34, 58, 13,137,186,121,233,112, 77,251, 41,252, 45,218, +104,106,106, 42,249, 97,195,134, 43, 18,177, 88,198,113,156,191,183,143,143,207,168, 23, 95,244, 2, 64, 39, 36, 36,240,143,105, +158, 41, 0, 72, 72, 72,224, 26,128,156,159,191,191,255,172,246,237,219,143,149, 72, 36,205, 10, 10, 10, 10, 10, 11, 11, 79,210, + 52,189, 4, 64,174, 27,244, 2, 2, 3, 3, 23, 63,243,204, 51,207,135,133,133,201, 79,157, 58,117,239,226,197,139,199,141, 70, +227, 66, 88, 86,136,253,223,176, 0,212,194,252, 5,222, 18,225, 83, 19, 7,182, 94,193,241,188,241,232,213,123, 95,174,140, 82, +239,159,153,137, 75,142,222, 85,222, 61,200,155, 42,148, 48, 87,168, 32,100, 41,252,113,233, 42, 94,127,125,102,229,115,138, 2, +126,207, 90,143, 70, 45,194, 21, 92,133, 6, 52, 71,112,232, 80, 86,244,234,245, 71,106,161,216,146, 63,125,226, 18,136,151, 31, +206, 92,202,199,249, 75,111,224,187,159,127,171,124,202,113,192,136,254,253,129,138, 34, 0,190,200,189,120, 25,162, 70, 1, 24, +208,175,139, 66,165,175, 67,102, 33, 20, 64, 40,244,232,214, 11,141,189,197,104,218, 72, 10,191,224, 32, 4, 74,124, 17, 40, 21, + 64, 36, 16,192,204,178, 80, 49, 28, 78,149,158,118, 88,168, 11,223,109,206,203, 4,229,240,243,242, 66, 72,163, 96,248,249,121, +129,167, 88, 48, 92, 5, 88,176,240,241,241, 66,163,198,205,144,123,165, 29,223,186,195, 15,117, 14, 74, 61, 99, 86,241,254,190, +222,240, 15, 8, 68, 72,163, 96,232,116, 58,136, 37, 82,136,140,150,197,249, 34,228, 45, 21,202,114, 21,158,121,107,125,116,126, +193, 29,148, 23,221, 66,217,249, 84, 71,194,128,211,131,196,208, 73, 67,163, 15,172, 63,144,233, 4,173, 7, 42, 4,228,229,229, +241, 0, 32,151,203,201,227, 66, 47, 60, 60,252,117,154,166,215, 3,192,216,232,104, 42,117,203, 22,119, 6, 95,203, 26,169,118, +134, 28,158,231, 65, 8,169, 60,219,238,217,210, 57,216, 73,205,149,245,228, 93, 97,254,157,188,205,204, 86,223, 0,255, 14, 0, + 32,150, 73, 65, 27,140,224,116,250,229,199,143, 28, 94, 16,251,225,220,142,105,203,146,242, 29,209,249,242,163, 68,222,170, 97, + 49,176,184, 32, 57,235, 56, 84,227, 88,212,125,200,243, 24,242,220,255,185, 84, 71, 55, 47, 29, 86,180,233, 18, 21,125,253,143, + 76,215,133,226, 88,165, 75,201,227,226,226,176, 37,246, 64,157,105,162, 15, 84,221,138,164, 83,128,229, 83,139,141, 28, 12,140, +165, 94,117,214,115,106,223, 0,180,243, 21,213, 73,111,197,138, 21,153, 31,189, 55, 59,116,244,216, 49, 62, 70,163, 1, 43, 63, +255,140, 90,189,122,181, 49, 49, 49, 49, 28,192,157,134,238,123, 99,198,140, 25,186,109,219,182, 12, 87,133,168, 73,147, 38,241, +121,121,121, 40, 43, 43,195,210,165, 75,225,235,235,139,168,168, 40,200,229,114,172, 95,191,222,221,126, 55,184, 87,175, 94, 27, +222,127,255,253,235,237,219,183, 95,223,179,103,207,203,247,238,221,107,150,149,149,213,235,205, 55,223,220,173,209,104,150,195, +178,149,187,179,136, 30, 59,118,108, 90, 82, 82, 82,176,217,108,134, 76, 38,131,183,183,119, 19,157, 78,247,242,232,209,163, 71, + 93,184,112, 33, 17,150,141,211,158, 56,156, 59,119,174,186,149,192, 57, 1, 96,101, 20,154, 3,104, 13,203, 18,135,172,206,196, +220,206,186, 86,252, 69,255,182,161, 51,159,233,212,100, 65, 99,127, 89,211,149, 40,218, 4,224,234,204,204,218, 55,169, 49, 85, + 40,209,184,205,179, 88,252,193, 88,172,183,227, 73,135,143,167, 64,167, 55, 97,228,208,153,120,122,192, 36,188, 26,247, 12,100, + 50, 9,104,150,129, 86, 79, 43,106,111,100,183, 0, 26, 24, 59, 97, 45,222,126,127,106,229,221, 17, 79, 71, 65, 42,149, 96,251, +161,223,176,231, 88, 22, 54,172,251, 10, 70,131, 9, 98,129, 16, 62, 94, 98,232,202, 10,162, 85, 5,168,113,135, 53,158,231, 1, +158,179, 28, 20, 7,158,231, 97,162, 37,149,203, 59,240, 52, 11, 86, 0,176, 96,193,210, 28, 24,182,110, 1,118,206, 91,114, 62, +208,143,129,159,175, 55,194,155, 69,160, 67,215, 54,240,245,145, 65, 93, 81,130,162,146, 34,148,171,239,193,108, 36,240,242,242, + 66, 72,200, 0,148, 22,135,240,141, 66, 63,171,217,140, 63,120, 30,207, 24,244, 48, 8, 1,177, 84, 12,131, 94, 12, 90, 47,134, + 81, 42,129,144, 48,224, 33,128,209, 80, 1,131, 94,139,102,205,154, 42,196, 2, 33,148,208, 32,148,158,128,234,107,204, 87,199, +167, 27, 62,117,216,128, 62,136,255,160,238,177, 50, 54,182,202,254,238,177,177,177,189,131,130,130,114, 8, 33, 70,158,231,133, +129,129,129, 94,185,185,185,193,214,213,221,154,186,219,144, 19, 19, 19,199,217,253, 70,148,187,171,197,213,200, 45, 9,225,167, + 77,155, 22,189,122,245,106,151,104,134,135,135, 39,244,233,211,103,201,192, 30, 61, 96,150, 72,144,156,156,204, 77,125,229,149, + 97, 41,155, 55, 31,112,241,247,177, 98,193,130,202,235, 89,243,231, 35,121,225,194, 58,175,157, 33, 91,141,185,243,189,123,247, + 6, 0,126,232,208, 86,157, 1,220, 72, 74, 74, 51,184,200,252,179,186,118,238,236,103,235, 51,222, 82, 25,238,150, 20, 67, 83, +174, 66,175, 62,125,189,118,125,183,238, 64,236,135,115, 59,167, 45, 75,114,180, 54, 59, 51, 99,201,106,225,107, 47,143, 18,182, +149,203, 57,171, 16,128,249,201,171,170, 10,209,179,166, 3, 0, 62,122, 47,209,173,237,164,221, 98,254, 54,164, 5,185,144,120, +168, 75,164,189,133, 4,231, 23,190, 5,226,215, 8,236,141,243, 48,221,248, 19, 57, 74, 29, 34,247, 22, 59,245,126,207, 94,189, +142, 78, 25, 31,223, 50,126,242,155, 1,105, 63,253,204,201,229,114,106,113,210,114,248, 46, 88,140,237,219,183, 23,166,166,166, + 82, 13,101, 5, 24, 51,102,204,176,109,219,182,237,223,182,109,155,237,122,184,237,127, 7, 2, 74,212,254,253,251, 21,183,110, +221, 66,235,214,173, 49,104,208, 32,248,251,251, 67,165, 82,225,206,157, 59,184,121,243, 38,134, 15, 31,206, 15, 31, 62, 60,122, +246,236,217,174,212,211,152,103,158,121,102,229,138, 21, 43, 54,245,236,217,115, 37, 33,228,142,221, 56, 78, 98, 98, 98,124, 0, +100, 89, 15,167,232, 37, 38, 38,166, 79,155, 54,141, 58,125,250, 52, 8, 33, 8, 14, 14,174, 60,246,238,221, 43,238,215,175,223, + 87,183,111,223, 62,241,164, 51,127,219,189,234, 66,128,176, 6,230, 31, 28, 25, 17, 28,223,163,101,208, 4, 66,136,136,231,121, + 51,103, 57,104,214,108, 52,136, 41,174,105,215,198,210, 15, 26,249,181,110,179,237,212,205,159, 87, 70,113, 71,103,102,214,190, + 91, 28, 32, 70,167,142,237, 65, 81,153,200, 81,149, 1,184, 12,117,225, 53,136,164, 18,236,216,253, 37,244,165, 44, 38,188,241, + 15,112, 28,240,226,168,254, 96,133, 62, 14, 63, 46, 39,231, 50, 56, 14, 24,217,157, 88,249, 74, 75, 24, 77, 52, 98, 70, 12,135, + 52,128,194,134,141,251, 64, 81, 64,250,207,235, 81,120,227,207,232,189,155, 86,100,214, 36,253, 0, 0,199, 3, 28,199,129,227, + 56,176, 44, 11,147,136,135,153,152, 65,211, 52,244, 94, 70,128,147,130,226, 89,176, 98, 30, 21,180, 17, 58,141,186,206,188,133, +248,152, 32, 20,202, 16, 28, 28,140, 54,109,218, 32,172,113, 95, 64, 64,129,101, 79,131,226, 85, 48,234, 24,176,156, 14, 69,119, +148, 8, 9, 46, 69,112,192, 0, 44, 91,177, 43,234,231, 31,239,167, 37, 51, 50,224, 77,165,128, 81, 2,154, 50, 67, 39, 22,162, + 66, 38,130, 80, 36, 6, 56,111, 16, 1, 65,133, 78,143,242,162, 91,200, 61,125, 12,202,252,124,112, 28, 7,138, 23,184,213,104, +190, 91,251,151,224,252,230, 59,111, 58, 30, 39,171,174,217,110, 76, 75, 75,155,251,254,251,239, 79,205,207,207,167, 8, 33, 33, +169,169,169, 63,195,178,185,147,151,187, 13,121, 74,108,172,104,205,154, 53, 27,239,221,187,135,244,244,116, 68,182,111, 47,104, +136, 14, 34,151,203, 73, 92, 92, 92, 20,207,243,138,213,171, 87,187,188, 97, 17, 77,211, 41, 3,173,109, 74, 44, 22,163, 93,187, +118,216,122,232, 80, 70, 72, 72, 8, 74, 74, 74,156,166, 99,211,236, 31, 0, 72,239,222,189,249,211,167, 45, 22, 43,187,243,159, + 67,134, 12, 41,156, 59, 55,214, 63, 41,201,241,154,251,177, 31,206,245,246, 54, 51, 91,187,118,238,236, 39,160, 40,188,251,218, + 4, 24,140, 38, 36,127,251, 45,188,100, 50, 24,141, 70, 24, 13, 6,116,239,217,163,237,111, 63,253, 52, 13,192, 23,142,172,142, + 11,103, 77,231, 0, 80,215,242,242,168,234, 12,191,122,247,116,231,195,155,119, 24, 28,125,251,202, 17,126,216,139,111, 69,103, +236,252,214, 45, 65,192,126,215, 62,219,150,182,117,221,119,132, 78, 1, 66,220,170, 96,113,120, 88, 8, 68, 51, 83,161,153, 16, + 1, 97, 96,168, 75,204, 63, 46, 46,174,200,172,211,223,153,252,238,212,230, 31,254, 99, 14, 86,175, 75,185,212,167, 87,175, 86, + 41,171, 82,188,222,155, 51, 27, 63,245,239,139,141, 27, 55, 78,132,101,215,210,250, 48,254,168,109,219,182, 41,108,204, 62, 53, + 53, 53, 23,150,109,218, 15, 58, 35, 0,236,223,191, 95, 17, 18, 18,130,158, 61,123, 50, 20, 69, 9, 45,214, 89, 14, 34,145, 8, + 65, 65, 65,104,220,184, 49,110,222,188,137,253,251,247, 43, 92,232,115,177, 47,188,240,194,103, 43, 86,172, 88,213,190,125,251, +181,132, 16, 14,192, 87, 0,158, 3,112,132, 16,178, 16,150, 53,243,103, 3, 88,232, 12,189, 21,137,137,155, 7,198,198,146,157, + 59,119, 66, 40, 20, 66,161, 80,224,252,249,243,104,211,166, 13, 22, 45, 90,132, 46, 93,186, 96,234,212,169,194,143, 63,254,120, +197,147,200,252,167,204, 93, 86,121,239,235,164, 15,107, 20, 2,106,154, 5, 64, 9, 5,148,144,225,120,173,193,204,220, 33,132, + 72,124, 36,130,110,126, 98, 68,202, 58, 15,105,141,232,183,129, 14,131,208,196,155, 31, 51,113, 64,196,135, 65,126, 94,195, 86, + 70,193,191,246,236,112, 16, 8,108, 99,182, 31,128,102,240, 15,127, 1, 6,214,136,181,169,235,240,195,198,116, 12,143, 30, 0, + 0,208,235, 1,129,176,118, 82, 50,175,246, 0, 0,150,181,223,155,166, 8, 64, 22, 40,129, 4,241,175,191,133,152,184, 56,236, +218,109, 97,100, 94,222,128,174,226,110,157,133,101,134,160,146,249,155, 25, 22, 38,141, 25,122,149, 30, 42, 51, 13,165,158, 70, +185, 73, 11,149,182, 2,229,197, 90, 40, 85, 70, 40, 43,106, 95, 66,253,221, 87, 91,241,132, 16, 8, 4, 4,132,146,128,101,121, + 48,250,124,232, 84,215, 80, 88,164,134,178,188, 2,106, 45, 11,101,185, 17, 5, 5, 69,184,116,229, 28, 84,234,115,232,219,171, +183,162, 54,154, 2, 0,148,214, 8,195,245, 59, 40,251,227, 50,202,242,111, 65,163, 86, 66,163, 86,226,214,165,211, 56,158,246, + 29,178,182,108, 64,201,245,235, 96,105,206,210,155, 4, 15,205, 13,104,219,135,155,142,137,137,233,184,120,241,226,247,155, 52, +105,162, 75, 79, 79,239,150,150,150,246, 43,128,158,214, 74,119,123,193, 41,113, 88,216, 44, 0,232,215,165, 11,166, 77,155, 86, +124,234,202,149, 3, 79,117,232, 16,213, 16,153,223,178,101, 75, 38, 0,146,152,104,209, 50, 19, 19, 19, 93,162,107,150, 72, 0, + 0, 91,183,110, 69,104,104, 40, 62, 76, 76,196,172, 89,179, 16, 18, 18,242, 88,248, 97,109, 76, 63, 53, 53,181,242, 0,128,195, +135, 15,135, 3, 24,229, 36,153,167, 2, 2, 3, 59, 8, 40, 10,111,196,196, 64,165,214,160,224,238, 29,136, 68, 66, 8,133,150, + 67, 36, 18, 65, 34,243, 66,107,185,252,243,158, 67,135, 58,165,177, 95,203,203,195,143, 91,127,173, 60,108,152,159,188, 10,243, +147, 87, 97,143,226,176,203,223, 59, 52,246,227, 40, 0,184,125,229, 72,230, 80, 11,243, 87,224, 49, 89,237,232,194,247, 95,160, +248,237, 94, 24,146, 81,130, 78, 1, 66, 8,252,130,192,148, 23, 35,114,111, 49,188,133, 22, 30, 40,112, 48, 39,235,230,245,235, +101, 95,167,254,167,253,247,255,249, 30, 95,126,251,213,173,175, 86,124, 54,255,253,233, 51, 70, 45, 94,178, 24, 50, 95,111, 12, +234, 55, 0,167, 78,158,250,254,181,248,215,220,254,102, 27,243,183, 93,239,220,185, 19, 79, 61,245, 84,107, 0, 19,156, 53,251, +155,205,102,244,234,213,139, 99, 89, 86,168, 86,171, 97, 50,153, 96, 50,153,112,229,202, 21, 40, 20, 10, 28, 59,118, 12, 77,154, + 52,129,217,108,198,164, 73,147,156,201,235,184,184,184,184, 47,198,142, 29,235,183,118,237, 90, 63, 66,136, 24,192, 97, 0,106, + 0,189, 0,252,106, 39,120, 30, 4,208,197, 17,189,109,239,191,191,121, 84,247,238,228,167,152, 24, 20,158, 61,139,207, 62,251, +140,219,181,107,215,255,187,125,251,118,168, 66,161,120,123,238,220,185, 48,155,205, 24, 48, 96, 0,188,189,189,251,227, 9,135, +189, 48, 80,167, 5, 96,102, 38, 74, 86,162, 36,229,247,235, 37, 25,145, 17,193,209,189,229, 65,150,117,196, 95, 88,132,223,125, +134,227,224, 31,197,232,223, 57, 16,207,200,119,193,247,183, 37, 61, 71,244,144, 79,216,120,228,210, 31, 53, 17,111,210, 54,150, +240,124, 1, 63,250,245,153,152, 53,253, 43, 0, 74, 0,190, 0, 76,104,217,190, 23,164, 18, 33, 12, 58, 19, 64, 91, 4, 4, 95, + 95, 95, 20, 43,107,221, 47, 27, 6,253, 85, 2,128,191,244,251,183,160,168,213, 85,148, 4,206,240, 39,140, 38, 51,100, 62, 82, + 64,108, 17, 16,180, 26, 13,250,247,239,143, 35,191,254, 84,187, 58,194,209,224, 56, 33, 24,134,129,201,100, 66,133, 80, 0, 33, + 77, 1,119, 53, 96,188, 24,176, 98, 14,188, 72, 0,189, 64, 8, 70,167,135,202, 84,123,172,147,175,143, 14, 12, 67, 96,162, 89, +168,212, 26,228, 92,207, 71,193,221, 82, 24,104, 51, 52, 21, 74, 84,104, 85, 48,178, 52,136,144, 64,167, 87, 67,163,191,137, 91, +133,106,148,105,117,181,210,100,237,164, 52, 70,173, 67,193,185,203,184,119,249, 38, 52,218,235,208,170, 84,224, 33,132, 72, 64, +192, 19, 17, 40,202, 98,245,117,197,185,246, 65,252, 7, 78,185, 3, 28,224, 30,128,123,243,230,205, 51, 0,192,220,185,115, 79, + 37, 37, 37,121, 91,179,110, 4,144,239, 46,225, 53,107,214, 44,141,137,137, 1, 0, 68,132,132,132, 90,125,226,130,134,236, 28, + 54,243,191,213, 18,224,176,248,194,195,195,135,210, 52,141,228,228,100,188,252,242,203, 24, 59,124,248, 95, 3,253,133, 11, 22, + 75, 80, 72, 8,239,108, 92,192,172,249,243, 43,125,254, 0, 48,123,193,130, 42,150, 1, 39,205,254, 85, 96,211,254,109, 76,223, +134,212,212, 84, 36, 36, 36,224,192,129, 27, 63, 2,248,201, 17,157, 0,161,240,223, 70,218, 4,129, 64,128, 43, 55,114,193,243, + 60, 46,229, 92, 3, 77,155, 65,129, 64, 40, 20,130, 16, 2,142,101, 97,208,233,113,237,247,223, 15, 57, 81,134,148, 61,211,127, +237,229, 81,246, 26, 63, 5, 0, 39,206, 92, 64,219,136,150, 46, 77, 83, 62,144,246,239, 74,109,255,128, 69,243,183,185, 66,248, +231,199,188, 21,189,119,155,123,214,128, 6,129,242, 46,196, 45,218,161,120,154, 20,146,103,198,129,205,222, 7, 86, 99,137, 55, + 40,158,246, 52, 90,166,102,129,229,234,110, 42,237,219,182,111,234,229,229,237,245,229, 55,107,140,209, 67,134,136,251,246,239, +247,211,254, 61,191, 61,127,229,122, 14,192,241,144, 74, 36, 24,208,123, 0,118,239,220,141, 17, 35, 70,240,251,246,237,115,122, + 40,168,174,245,239,223,191, 31, 55,110,220,160, 1,136, 79,158, 60, 73, 79,157, 58,117,124,106,106,234,107,142,232,228,229,229, +161,117,235,214, 0, 64,229,229,229,225,252,249,243,104,217,178, 37, 34, 34, 34, 80, 94, 94,142,236,236,108,180,106,213, 10,161, +161,161,104,217,178, 37,242,242,242,234,110, 40, 20, 21, 31, 23, 23,183,100,240,224,193, 62,167, 78,157,242, 99, 24,102,178, 76, + 38, 27,109, 48, 24, 86,192,178,245, 57,172, 2,192, 42, 88,182, 86,167, 81,199,244,118,145, 72, 20,159, 54, 99,198,250,167, 67, + 66, 72,201,156, 57,232,207,113, 88,181,115, 39, 95,168,215,191,133,191,182,101, 95,127,233,210,165,181, 12,195, 8,125,124,124, + 16, 30, 30,238, 99, 54,155, 33, 18,137,240,119, 67, 77, 46,128, 48, 0,173,199, 68,182,120,183,121,176,247, 4,152, 13, 64,251, + 97, 56, 19, 50, 6,207, 36,126, 7, 67,169, 10, 2, 63, 95, 40, 86,198, 99, 80,167,223, 17,116, 33, 99, 48,128, 22,181,253, 64, + 27,191,102,248,227,194, 47,118, 6, 7, 29, 44, 91, 40,155, 1,179, 9, 66, 78, 0,202,202,196,183,109,119,188,139,200,190,139, + 60, 70,244,236, 82, 77, 9, 21, 2, 16, 1, 34, 41, 24,194,194,170, 7,227,149, 9, 51, 0, 64,145,244, 81, 98,173, 29,129,229, +120, 48, 28, 5,138, 97, 64,209, 38,232, 41, 75,219, 49, 8, 4,240,102, 12,208, 24,120, 16, 17, 1,203,178,208,179, 64,177,174, +246,141,159, 24,154,131, 81, 36, 0,167,103,192,112,106,104, 43,204, 16, 16, 17, 76,140, 25, 52, 79,131, 49,211,128,152, 3, 69, + 0, 34,225,160, 54,176, 40, 42,209, 67,103, 98,106, 84,146, 41,194, 86,238,195, 75,200, 95, 46, 93,179,209, 0,181, 82, 9,138, + 8, 32, 20,242, 0, 47,132,128,184,175,234, 92,189,117,149,110,223,178,189,216, 25,179,127,109,178, 25,236,118,196, 74, 74, 74, + 26, 5,224,246,220,185,115,123,250,251,251, 7,168,213,234, 91, 73, 73, 73, 46, 19, 77, 76, 76,124,115,205,154, 53,104,220,184, +177,253, 61,213,170, 85,171, 14, 60,213,161,195,208, 83, 87,174, 28,108,168,142,144,152,152, 24,109,231, 10,168,139,249, 71,245, +233,211, 39,124, 96,143, 30, 32,190,190, 72, 74, 74,194,156, 57,115, 32, 18,137, 96, 46, 47,135,191,191, 63, 62, 76, 76,172,140, + 11, 72,136,139,115, 40, 4, 84,247,241, 59,138, 9,168,203,163, 80, 93,251,119, 96, 29,112,216,100,202,149,202, 14, 62,190,190, + 40, 45, 47,135,226,196, 9, 8, 41, 1, 76,102, 51,244, 6, 3, 56,142,171, 20, 92, 24, 51, 13,218,100,114,198,165,193, 1,160, +172,110, 0,206,174,225, 27,173,247, 49, 63,121,149, 24, 0,218,202,229,197, 55,107,214, 45, 92,178, 82, 53,107, 29, 25,181,119, +219,183,174,152,155,107, 47, 96, 23,204,254, 85,204,178, 91,254,131, 30,175,255, 3,146,136,110,150,177,162,244, 46,114,148, 22, +193, 95,210,255, 5,228,179, 12,188, 86,215,237,106,214,104, 52, 1, 18,153, 20,109, 34, 34,164, 55, 11,110, 55, 41, 43, 41,195, + 43,175, 77, 80,236, 57,152,129,149,203,146,211,183,237,217, 25,211, 54,162, 45,226, 95,158,136,172, 51,199, 48, 98,248,112,126, +223,254,253, 14,191,217, 94,235,223,191,127, 63,134, 13, 27,102, 19, 22,197,119,238,220,193,212,169, 83,197, 0,224, 76,108, 65, + 89, 89, 25, 6, 13, 26, 4,150,101,145,151,151,135, 99,199,142,161, 83,167, 78,240,247,247, 71,243,230,205,209,163, 71, 15, 80, + 20, 5,138,162,208,164, 73, 19, 71,237,180, 83,151, 46, 93,190,232,223,191,191,224,194,133, 11,126, 44,203, 22,109,221,186, 85, + 99, 48, 24,146, 0,216, 59, 77,223,125,254,249,231,243,247,236,217, 19, 65, 8,185,139,218, 55,230,233,153, 48,112,224,250,190, + 66, 33, 41, 89,178, 4,188,217, 12,133, 64,192,101,233,245,147, 96,217,198,221,134,119,230,205,155, 39,164, 40, 10, 74,165, 18, + 55,110,220, 40,238,210,165, 75, 40,254,134, 16, 86, 99,254,109,195,252,101, 3,159,239, 30, 62,213, 79, 38,234,195,176, 92,185, +144,103,253, 16,208, 68,112, 87,101,132,161, 84, 13,136,133, 96, 85, 90, 20,148,211, 64,112, 11, 80, 28, 45,173,203,196,123, 93, +163, 65,187, 0, 63, 48, 38,224,122,230,143,104, 19,245, 92,165, 2,103,166,205, 16,129, 66,133,209,178, 67,237,136,168, 94,144, + 5,135, 99,197,250, 95,107,205,240,136,174, 4,123,206,243, 16, 73, 1,113,139,231, 64,231, 31,173,180, 2,136,196, 18,152, 97, +132,143,204,178, 35,233,206, 61,155,240,199,201,204, 58, 77,146, 28,199, 65, 76, 27, 96,134, 24, 20,197, 0, 70,203,192,102, 54, +155, 97, 50,138, 32, 16,138, 0, 35,192,115, 22, 23, 65, 75,121, 4,144, 85,243,140, 2,189,145,131, 64, 64, 96,102,204, 48,154, + 56,104,180,150,118,104,230,120,208, 38, 14, 16, 2, 2,145, 0, 66, 41, 64, 12, 44, 56,194,128,131, 1, 90, 3, 0, 56, 30, 88, + 88, 0, 20, 7,240, 4,160, 40, 14,132, 8,192,241, 4, 20,101, 85,156, 56, 10, 28, 69,129,112,206, 41,200,118, 65,126,226,122, +182, 35,111, 0, 33,115,231,206, 45, 78, 74, 74,138, 6,240,210,220,185,115,135, 39, 37, 37,233, 0,148,185,101,178,138,141, 21, +175, 89,179,230,219,152,152, 24,200, 27, 53,170,188, 47,111,212, 40,192,106, 5, 8,121, 20, 29,134,166,105,133,205,247,207,107, +181,248,228,147, 79, 96, 42, 43,131, 45,242,173,141, 85, 88, 17,153, 76, 24, 53,106, 84,113, 97,113,241,120,103, 52,237, 6,116, +201, 84,177, 0,212, 97, 33,192,233,211,167, 73, 77,194, 67, 21,161,214, 68, 67, 69, 43, 97, 52, 26, 17,224,239, 15,169, 88, 2, + 51,203,128,231,121,176, 44, 11,154,166, 97, 54,155,193, 49,172,179,241, 12,220,181,188, 60,170,173, 92,110,211, 8,184,107,121, +121,212,143, 91,127,149,218, 91, 4,218,202,229,170,134, 50,223, 23,228,102, 55,152,230,239,110, 12,192,144,140, 18, 20,203,211, + 33,110,209, 14, 36,162, 27, 90,174, 59,139, 82, 35, 7,111, 33, 1,253,223,237,184,122,227, 38, 28,237, 90,108, 96,104,156,206, + 58,137, 47, 86,124,142,167,163, 6, 98,222,255, 91,128,223,246,254,134,159, 54,252,128,254,131, 7,198, 52,151,183,128,208, 75, +132,131, 71, 15, 98,227,247, 63,224,151,237, 91, 33,150, 74,249,157, 59,119,214,185, 62,196,182,109,219,170, 48,126, 27, 84, 42, +149,203,229,163,213,106,225,239,239,127, 2, 64, 95,185, 92,142,222,189,123, 67, 32,176,184, 89, 91,182,108, 9,137, 68, 2,181, + 90, 13,185, 92, 14, 95, 95,223, 91, 90,173,182,101, 29,228, 46, 93,184,112, 97,233, 47,191,252, 50,178,109,219,182, 29,182,110, +221, 90, 81, 94, 94,190, 16,192, 70,123,249,101,200,144, 33,239,175, 91,183,110, 11,128, 98, 0,177, 0,126, 7,208,189, 6,122, +103, 87, 43, 20, 75, 3,178,179, 63,122,149, 97,240, 57,192,125, 91, 81, 49,177, 26,189,151,102,204,152,241,249,148, 41, 83,112, +243,230, 77,236,222,189, 27, 12,195, 28, 2,240,234,147,194,212,123,244,232,129,115,231,206, 85,250,253,235,180,176, 84,187,110, + 53, 38,178,197, 98, 63,153,168, 79,137,198,248,219,241,107, 37, 73, 16, 72,128,171, 71,241,172,156,199, 63,167,143, 66,239,206, +114,204, 72,120, 30, 47,182,166,129,139,251,193,139,100, 12,234, 12,214, 81, 33, 71,149, 15,161, 4, 24,241,226, 63,176,241,203, +101, 22,101, 81,111, 2,107, 0,182, 43,206,225,192, 41,203,140,194,102, 45, 34, 64, 9, 29, 51,175,145,221, 9,204, 70, 96,231, +238,125,136, 28, 62,221,162,253, 67, 4,129, 12,136,123, 33, 22, 35, 7,143,182,116,252, 91,185, 96,140,117,111,213,204,243, 60, + 24, 98, 97,240, 38,218, 18,252,103, 50, 26,160,215,235, 81, 81, 81, 1,173, 70, 13,173, 86, 11,141,202,162,101,189, 0, 0, 32, + 0, 73, 68, 65, 84,182, 2,198,138, 10, 24, 12,134,218, 27,127, 5,129,193,200,194, 96,100,161,211,155,161,173, 48,161, 92,107, +130, 74, 67, 67,173, 53, 67,165,178,156,149,101, 12,148,229, 12,148,106, 6,165, 74, 26,247, 74,107,207, 35,197,243, 96, 1, 16, +150,128, 80, 28,120,194, 3, 60, 15,158, 23,128,229,254,170, 62,206, 58,122,184,106, 27,239,216,191, 35,142,237, 57,134,223, 14, +253, 86, 41, 20, 92,189,117,213,213, 54, 23, 14,160,245,242,229,203,207, 3, 88,253,225,135, 31,190,215,170, 85, 43, 38, 53, 53, +149, 36, 39, 39,187,172,117, 77,137,141, 37,226,176,176,109, 0, 16, 22, 22,118,223,243,105,211,166, 49,217, 87,175,110,106,168, + 88, 0,155,249,223,217,125,227,109,190,127, 0,216,188,121, 51,174, 23, 21, 1, 0,118,101,102, 86,121,118,245,234,213,208,144, +144,144,242, 71, 49, 8, 12, 29,218,202, 54,239,186,202,125,219,181,237,185, 35,120,249,249, 94,225, 88, 22, 26,101, 57, 74, 75, + 75, 81,166, 42,135, 78,175,135, 78,175,135,182,162, 2, 58,181, 6, 90,149, 10, 70,131, 30,180,209, 8,142, 97, 29,142, 57,109, +229,114,219,152,193, 1,160,237,221, 1, 0,240,227,214, 95, 49, 63,121, 85, 0,128, 48,151, 27, 98,235,200,168,234,130, 67, 68, +167, 33, 81,143,122, 80,190,251,138, 28, 45,215,157, 5,137,232, 6,211,225,116,220,122,163, 39,188,133, 4, 71,135,133,128, 81, +151, 32,114, 95, 49,132, 14,154, 95, 70, 70, 6,121,123,230, 59,184,126,245, 42,178, 50,143,194,223,215, 31,227, 94, 25,135,128, +224, 32,156, 57,153, 13, 31,177, 20,222,222,222,104, 34,111,138, 77, 63,111,194,135, 31,127,132, 10, 55,152,184, 13,189,122,245, +114,249, 29, 95, 95, 95,168,213,234,190, 20, 69,209,205,155, 55, 71,159, 62,125,208,185,115,103, 52,106,212, 8, 82,169, 20,114, +185, 28,221,187,119, 71, 64, 64, 0,180, 90,109, 75, 95, 95, 95, 71, 36, 63, 61,124,248,112,198,134, 13, 27, 68,229,229,229,243, +170, 49,235,216, 65,131, 6,125,177,110,221,186,239,194,194,194,150, 16, 66,124, 0,124, 8,160, 46, 51,217,199,139,181,218, 79, +223, 98, 24,246, 91,131, 97,124, 53,122, 49,175, 38,252,235,151,233,239,205, 18, 92,189,122, 21, 39, 78,156,192,186,117,235, 42, + 0,252,243, 73,211,236,171, 7,189,215, 22, 4, 95,125, 16,144, 8, 40,226,155, 95,166,251,105, 83,214,205,127,158,187,165, 60, +105, 96,201,117,148,222,132,244,151,119,177,100,128, 22,217, 11,251, 96,101,116, 5,188,183, 79, 3,148, 5,168,224,165, 23,173, +146, 87, 45,248, 43,170,255,252,133, 95,241,175,127,109, 64, 27,191,174,248,243,248,121,236, 87, 92, 70,116,255,206, 24, 54,200, +210,208,120,129, 16, 52,235,252, 71,142,232,217, 1,139, 63, 93,134,125, 23, 53,240,145,119,194, 11, 47,140,194,111,135,182, 97, +247,111,155, 44, 31,199,154, 33, 17,213, 61,206,241, 28, 11,150,179,104, 51,176,106, 51, 52, 77,195,104, 52,194, 96, 48, 64,167, + 55,192,160,215,193,160,215, 65,111, 50,130, 54,213,190,237,115,153,193, 23,234, 10, 22, 26, 3, 7,141,129,179,252,175,229, 80, +161, 99, 80,161,103, 80,174,100, 81,166, 52,163,172,220,140,178, 50, 51, 74, 75,105,220, 43, 53,215, 41, 0,252,101,254,191, 95, + 85, 19, 10,120, 8, 8, 1, 95, 45,234,159, 39,142, 21,167, 15,226, 63, 64,199,254, 29, 43,175, 15,172, 63, 80,105, 17, 56,182, +231, 24,174,222,186,122,211,149, 6,151,158,158,254, 95,158,231,187,196,196,196,196, 71, 68, 68,132, 0,160, 56,142,147,152,205, +230,192,153, 51,103,250,213, 98, 10,174, 17,226,176,176,249,107,214,172, 25, 25, 19, 19,131,136,144, 16,167, 92, 87,245, 52,255, + 71, 1, 64,100,135, 14, 14, 3,216,218, 54,110, 28,157,156,156,140, 63,111,221,210,252,178,127, 63,174, 92,185, 82,169,245,183, +111,223, 30,214,103,244, 47,251,247,227,214,173, 91,184,154,157,109,112, 68,115,214,252,249,152,189, 96, 65,165,121,223,246,191, +237,218,246,191, 43,177, 0, 73, 73,105,252,144, 33, 67,222,181,103,250,182,115,239,222,189,145,148,148,230,148,118,125,237, 74, +110, 54,195, 48,160,105, 19,148,247,138, 81,114,183, 8,165, 69,247, 80, 90,116, 15,202,226, 18,168,202,202, 96,210,233, 44,241, + 51, 42, 21,156, 8, 2,100,230, 39,175, 18,206, 79, 94, 37, 4,160, 1,192,245,237,213,237,190, 68,118,113, 1, 78,163,105,235, +200,168,194,220,108, 69,247, 62,127,229,161,117,207, 23,163, 84, 37, 55, 20,245,105, 31, 36,174,188,138,230,239, 14,114,148, 58, +228, 79,126, 10,252,205, 11, 8,253,207, 25,120,175, 61,141,187,175,200,209,123, 95, 49,136, 72, 2, 33, 1,132,148, 99, 1,244, +194,197,139,228,147,101,139, 49, 99,246,251, 48,115, 44,174,228, 93,195,132,113,227, 33,150, 74,177, 99,251, 78,192,204,194,100, + 52,225,104,246,113, 24, 12, 21,152, 50,105,210,225,183,223,126,187,174,186, 38, 99,198,140,137, 30, 62,124, 56, 8, 33,200,200, +200,184,207,164,255,193, 7, 31, 56,253,157,193,193,193,184,115,231, 14, 0, 8, 83, 82, 82, 80, 82, 82,130,174, 93,187, 34, 32, + 32, 0, 20, 69,225,228,201,147,160, 40, 10,132, 16,220,185,115, 7,193,193,193,206,144, 93, 66,211,244, 96, 0,155,237,238,141, + 27, 52,104, 80,242,228,201,147, 3, 83, 82, 82,164,132, 16, 10,192, 54, 88,102, 1,220,115, 64,111,206, 9,179, 57,178, 58,189, + 87,231,254,178,229,229,241,211,200,200,119, 82,144,121,226, 18,146,147,147, 57,141, 70,243, 38, 44,179, 11,158, 56,244,232,209, +163,242,112,202, 5, 0, 32,119,211,241,155,137, 74,157,233, 52,128, 28, 0, 77,178,174,149,124, 61,184, 67,216,199,194,155, 39, +130,176,110, 34, 32,241, 6, 76, 58,128,231, 97, 22, 72,239, 29,253,243,238,183,168, 99,245,165,141, 63,125, 21, 61,126, 66,188, + 2, 0,116,156, 25,215, 85,249, 0, 88,180,241,139, 64,116,116, 55,132, 53,106,140, 50,181,198, 98, 43,160, 25,220, 85,233,234, +252,168,102, 45,250,163, 32,223, 58,205,147, 8, 49,162,187, 37, 6, 96,223, 69, 51,126,219,149,142,123,165,119, 16, 28, 96,153, + 73, 16, 32, 22,161, 91,100, 15, 40,182,215, 97,210,133, 16, 98,142, 1, 11, 1, 56, 66, 64,177, 28, 96,102,192,138,132, 0,161, + 96,235,147, 28, 15,203, 90, 1,117, 96,175,226, 38,121,126,160, 47,239, 37,230, 33, 20,217, 89, 24,204, 0,195, 3, 70, 26, 96, + 77, 44, 8, 33, 32, 98, 2,134, 5,116, 38,224,100,150,154,244,232,209,156,175,209,228,111,227,150, 20, 7, 98, 53,255, 91,132, + 2, 2,150,163, 64, 9,172, 51, 5, 0,240, 2, 30,224,157,179, 2,216, 51,255,154,174,143,237, 57, 22,225,108, 67,139,137,137, +233,156,158,158,254, 57,128, 30,233,233,233,251,210,211,211,143,198,196,196, 36,182,110,221,218, 76, 8, 9, 94,185,114,229,254, + 15, 63,252,112,194,178,101,203, 14,215, 33,124,218,180,127,225,236,217,179,231,207,158, 61, 27,251,246,237,131,238,222,253,125, + 57, 34, 36, 4, 55,111,222, 4, 0,133, 51, 11,249,212,182,232, 79, 98, 98, 98,212,154, 53,107, 20,171, 87,175, 70,100,251,246, +209,167, 46, 95,118,104, 42, 62,126,241, 98,230,128,255,207,222,151,199, 53,121,108,239, 63,147,141, 0, 42,130,187,104, 85,172, +168, 85,235,130, 21, 80, 43,137,162,181, 90,187,252,106,212,234,181,245,171, 45, 65,237,117,235,130,182,182,118,209,170,189, 23, +181,171,196, 46, 87,187, 88, 37, 88, 91,183,186,160, 9, 42, 34,136, 86,235, 10, 8, 42,130, 11, 74,194,150, 0,217,230,247, 71, +242,198, 16, 3,121, 19, 80,180,125,159,207, 39, 31,222, 45,135,201,204,188,243,156,115,230,204,153,190,125,159,186,112,236, 88, +103, 0, 62, 0, 62, 55,250,248, 64, 88, 93,141,110,237,218, 97,193,130, 5, 72, 77, 77, 93, 25, 26, 26,154,146,154,154,186,191, +160,160,192,141,114,119,119, 30,128,122,196, 0,212,208, 3, 83, 82, 82, 72, 92,156,236,216,209,163, 69,169,114,185, 92, 4, 0, +113,113,178,193, 43, 87, 42,211,192, 50, 9, 80,231,190,143,189, 83,121,253,198, 40,139,201,220, 67, 87, 90,138,210,219,183, 64, + 8, 15,148, 90, 80, 85, 85, 5, 74, 41, 40,165,184,116,238, 60,140,134,106,252,153,156,236,174, 14, 29,199,156,230, 0,120, 99, +164, 81,150, 49,210, 40, 56, 46, 11,180, 77, 17,176, 70,135,110,131, 36, 5, 57, 25, 42, 0,232,220,169, 19, 78,101, 88,245,228, +220, 63,183, 1, 0, 90, 61, 50, 64,122, 43,255, 68,163, 13,198, 3,255, 40, 66,230,211, 64,191,176,104, 20,205, 30,140,182, 95, + 31, 65,182, 70,135, 64, 17, 65,177, 70, 11, 1, 33,110, 61, 0,246,119, 51, 53,181,198,147, 93,187,118,165, 99,198, 62,141, 29, +219,118, 32, 49, 49, 17, 31,188,251, 30,246,170,247,131, 47,224, 35,184, 67,112, 84,105,105,221, 75,151,183,110,221,170,182, 41, + 2,146, 81,163, 70,213,136, 5,216,183,111, 31, 46, 94,188, 88,165, 80, 40,218, 57,123,147, 92,246,151,206,157,145,151,151,135, +199, 30,123,204, 52,111,222, 60,209,166, 77,155, 16, 16, 16,128, 11, 23, 46,220,229,121,205,203,203, 67,103,246,237,236,152,120, +110,234, 19, 79, 60,241,209, 75, 47,189, 20,144,153,153,217,180,170,170,234,255,124,125,125,159,177, 5, 6,254,206, 82,158,227, + 66,249,169,207,252,123,211,134,161, 35, 94, 32,159, 38, 3,164,253,179,248,100,205, 59, 84,147,115, 97, 58, 0, 37,254,198,168, +161, 0,204, 85,227,236,103,146,234,236,185,106,251,148,102,254,103,146,146, 63,202,171, 76,186,240, 71, 91,142, 9,242,227, 63, +193,175,174,242, 55, 81, 94,121,113,185,225,104,218,197, 27,123, 10, 53,250,148,185,106, 92,175, 77,201,152,242,175,197,234,131, + 71,210,164, 0, 84, 22, 62, 51,205,199,199,197,178,235,120,255,245,233,208,235,171, 81, 86,105,141, 1, 48,240,124,176,121,107, +221,105,118, 11,242,211,200, 11,207,254,219, 74,150,102,198,114, 54, 97,116, 31,130, 73,179, 86,193,207,207, 7,205,124,197, 82, + 0,170,156, 51, 39,164,235,191,216, 90,231,128, 36,160, 38, 24,136, 85, 9, 0, 33, 48, 83,106, 85, 4, 76,182,229,126,132, 7, +129,197, 2,147, 45, 56,208,157, 18, 80, 82,217, 28,149,213,197, 16, 9,120,246, 52,103, 38, 11, 96, 52, 82, 24, 77, 20, 21,149, + 22, 16, 62,129, 25, 4, 70,203, 29,215,189, 43,152, 45, 60,240,136, 25,196, 76, 64,121,212,238,254, 39,181, 24,207,140,164,179, + 23, 54, 17,119,185,161,207,167,157,175,111,223,177,187, 45,250,244,233,115, 61, 36, 36,228,133,203,151, 47,119, 75, 76, 76,204, + 0,240, 92, 82, 82,210,115,142, 15,175, 88,177, 66,189,112,225, 66,233,138, 21, 43,220, 17,132,189, 66, 98, 99, 99,107,125,232, +197, 87, 94,177,250, 0, 61, 75, 12, 68,157,220,254, 0,128, 65, 61,123, 74, 51, 88,144,191,125, 0, 62,117,202, 30,173, 58,184, + 79, 31, 75,124,124,252,151,227,198,141, 51,101,101,101, 9,174, 92,185,130,206, 45, 90,164,237,216,177,131, 85,128,226, 61,202, + 3,224, 72,238, 55, 83, 82, 82, 28, 99, 60, 78, 59,212,179, 91, 37, 64,185, 98,165, 78,182, 48,238,197, 11,251, 15,164, 53,247, +247,111, 86,166, 45,129,201,100, 2,181,189, 7,218,155, 69, 40,211,106, 65, 41, 69,255,232,104,233,159,201,110,243, 32,153,112, + 39,230,132,103, 91, 14,200, 11, 31,240, 56,198, 72,163,236,171, 0,114, 46, 95,102,173, 4, 68,143,125, 73,146,188,243, 23,187, +149,255,187,242, 59, 21, 0,180, 10, 25, 34,189,149,151,170, 6,128,198, 33,127,122,183, 18,128,111,208, 47,246,125,220,176, 88, +208,119,125, 6, 50, 70,183, 65,175, 29, 55, 33, 32, 64, 83,161,119,123,179,237,216,177,131, 76,124,105, 34, 29, 62,114, 4,182, +109,249, 13, 31,175, 92,129,184,210, 82, 80,139, 5,155, 55,111, 65, 97, 97,225, 51, 0,118,184,147,227, 74, 17, 0,128, 23, 94, +120,225, 36,128,114, 54,101, 89,191,126, 61, 25, 53,106, 20, 61,113,226,132,104,192,128, 1, 24, 49, 98, 4, 84, 42, 21, 30,121, +228, 17, 84, 87, 87, 35, 42, 42, 10,148, 82,203,137, 19, 39,120, 66,161,208,155,140,128,143, 5, 4, 4,172,158, 56,113,162,240, +220,185,115,205,170,171,171,107, 11, 12,100,139,254,193,253, 38,108,232, 55,108, 34,249, 46, 5, 40,171, 4, 12,151,118, 91, 52, + 57,170,105,168, 25, 24,248,208,128,201, 3,224,104,249,187,186,230,210,149,234, 64,254,204,249,249,207, 36, 21,249, 87,110, 87, +164, 1,104,103,123,121,171, 1, 20, 2,200,155,171,134, 91, 23,167,226,235,157,234,161, 67,251, 72,205,180,137,202,241,229,168, +208,149, 89,215,253,243,252,144, 91, 14,178,230,235,141,172,126,224,214,109, 95,144, 91,154, 60, 9,120,122,149, 35, 23, 54,105, + 18, 0,179, 81, 11, 80, 29, 70,247, 97, 55,161,107, 4, 31,160,212, 74,212,224, 67, 68,109,138,128,141,252,173, 57, 0, 1,152, +217,205, 77,164, 29,191, 74,194,122,183,163, 38,163, 6, 2,219,194, 94, 74, 41,204, 38,138, 42, 35, 80, 86,110,130, 17, 20, 38, +202,131, 64, 72,112,251,166,177,214,114, 30, 59,182,146, 0,192,224,200,183, 40, 49, 90,173,127, 10,128, 82, 2, 80,155,197, 64, +249, 32,124, 11, 44, 22, 1,178,115,182,176,250,205,175,126,252,170,244,114,238,229,186, 8, 88, 8,235, 82,141,186,216,201, 94, +243, 75,150, 44, 97,252,163,167,108, 86,241, 29,162,126,241, 69,201,150, 45, 91, 84, 54, 37, 64,229, 78, 9, 88,167, 84, 26,255, + 60,125, 90,214,185, 79, 31,243, 19, 61,122,232,108,125,180,218,230, 16,177, 67, 54,122,180,213,226,232,211,199,253,116,199, 91, +111, 73, 1, 96, 96,247,238,119,221,203,204,202, 82,103,156,247, 94, 25,234,211,179,231,215, 60, 30,207,124,225,216, 49,255, 54, +109,218,220, 78, 45, 40,216,224,206,234,191, 15,172,227,216, 15,116,182,128, 63,102,106,160,194,169,173,217, 40, 1,231,100, 11, +227,194,183,125,251,221,150,144, 46,157, 31,171,174,174,130,217,104,130,197, 98, 65,211,192, 64,148,106, 52, 12,249,179, 81,162, + 74, 62,124,227,223,173, 1, 24,114, 46, 95, 22, 49,243,255,233, 39,254,194, 24,105,148,101, 73,252, 23,238,146, 3,217, 49,107, + 78, 28,189,144,117, 65,234, 72,254, 0, 48,252,169,231,164, 7,246,252,174,190,149,151,234,125, 37,214, 18,224,231,250, 58,123, + 14, 27,248, 71, 17,240,199,235,246,243, 71,127,191, 97, 63, 46, 53,154,189, 46,239,230, 95, 54,147, 33, 67,134, 60, 61,106,236, +232, 93,175, 77,157,113,248,241,190,125,134,110,251,125, 59,210, 78, 30,199,241,227,199,119,214,229, 6,174, 67, 17,152,177,117, +235,214,111,183,110,221, 26,177,117,235, 86,214,133, 27, 53,106,212,240,189,123,247, 30,216,177, 99, 7, 66, 66, 66, 48,114,228, + 72, 4, 4, 4,100,151,150,150,134,158, 61,123, 22,121,121,121, 60,161, 80,136, 81,163, 70, 69,239,221,187,215,211,159,122,174, +180,180,116,229,246,237,219,235, 10, 12,244, 4,127, 22,158, 76, 92,254, 91,210,179,239, 84, 6, 79, 65,229,177,197,150,107,135, +150, 77,173,135,188, 7, 78, 17, 96,237, 1,168, 13,115,213,208, 1,248,203,246,241, 10,135, 15,159, 86,199,198, 46,148, 38, 40, + 62, 86, 5,119,234, 6,160, 26, 66, 31, 49, 10,174,151, 97,227,142, 84,226,185,188,157,234,105,175,206,199,250,239,127, 5, 44, + 87, 0, 8, 96,170,170, 68,112,187, 0,233,178,183,102,176,182,230, 96,182, 64,192,179,192, 72, 4, 16, 82,211, 29, 69, 0, 38, +128,154,193, 54, 48,204, 17,199,207, 92, 39, 0,208, 54,136, 71,133, 2,171,181,111,178, 88, 19, 24,149,148, 83,152, 77, 0, 95, + 96,129,217,196,110,228, 56,146,246, 31, 2, 0,225,131, 22, 80, 48, 57,225,121,128,133, 88,221,253, 89, 57,219, 61, 42,228,183, +239,125,171,110,128,254,197,202, 92, 97,200,223,193, 19,224,118, 57,214,177, 11, 23,146,142, 57,185, 12,235,120,214,237, 51, 13, +153, 58,248, 46,229,214,186,196, 47,193,106, 91,123,183,111, 72, 3,231, 1,112,174, 91,157,155,165, 86,172,250,142,114,197,202, + 11,178,133,113,189, 1,240, 47,164,164, 24,171,244,149,176,152,205,232, 25, 22, 38,109, 23,250, 24,142,253,177,157, 93, 29, 83, + 50,113,207, 31, 59,237,167,131, 31, 11,177, 31,239,249, 99,231, 93,231,117,133,198,127,253,185, 85, 65, 30,241,212,243,210,115, + 23,114,113,253,202,105, 21, 0, 28,216,243,187,170,205, 35,189,165, 55,243,207,120,220,238, 19, 38, 76,128,167,233,125,205,196, +167,206,251,249, 47,180,197, 31,215,170,238,249,128,159,154,154,250,135, 66,161,224,101,102,102, 90,246, 31, 77, 65,139,150, 45, +156, 87,122,120,132,173, 91,183,126,167, 80, 40,126,144,203,229, 70, 79,190,247,230,155,111,170, 0,144,105,211,166,209,220,220, + 92,100,100,100,160,188,188, 60,180,105,211,166,104,209,162,133,125, 47, 0, 47,200,159,193,127, 82, 82, 82,132,105,105,105,125, + 12, 6,195, 98,212,156,203,247, 6,239,158,217,252, 47, 97, 64,215, 31, 22,148,230,238,157,210, 0,242, 26, 21,204, 42, 0, 87, +215,189, 82, 0,220, 14,130, 10,133, 96,237,218,181,238, 93, 85,123,142,168, 59,116, 30, 65,110, 22,164,209,214,193, 29,161, 41, + 55, 97,227,182,195, 94,119,208,245,223,174,182,125,183, 13, 5,110, 34,176,169, 0,203, 22,189,230,209, 75,255,205,209,156,123, +182,129,205, 13,141,133, 0,128,216, 87, 72, 13,149, 70, 88, 0,248,249,249, 65,111,210, 19,179,201,115,121,233, 25,214, 61, 3, +194,159,152, 79, 45,148,143,203,151,118, 53,230,238,102,108,151, 14,114,187, 4,178,168, 31, 71,194,111,224,105, 1, 67, 92,156, +204, 7,128,121,229, 74,165,185, 62,130,148, 43, 86, 50, 27,249,216,219, 52,247,140,103,235,244,231, 44,255,194, 43,101,204,121, + 43, 96, 71,236,223,243,155,218,185,175,221,204,247, 46,127,128,187,141,125,156,117, 96, 19,241, 65, 37,175,238, 21,169,185,229, + 38,132, 54, 21,220,151, 87,197,182, 86,191,193,222, 57, 79,201,191,198,248,236,253,134, 63,108,240,137,193, 96,248, 13,112,191, + 41, 29, 75,188, 93,154,187,119, 35,106,198, 6, 60,212, 74, 0,171,193,199,219,125,132, 57,112,112, 68,183,110,221,144,147,147, +195, 85, 4, 7, 14, 28, 56, 60, 36,224,113, 85,192,161, 33,192,145, 63, 7, 14, 28, 56,112, 10, 0, 7, 14, 28, 56,112,224,192, +129, 83, 0, 56,112,224,192,129, 3, 7, 14,156, 2,192,129, 3, 7, 14, 28, 56,112,104,116,212, 8, 77, 61,121,242,164,215, 81, +155,174,130, 9, 57,121,156, 60, 78,222, 3, 35,175,206,232,112,174,254, 56,121,156,188,191,151, 60,143, 21, 0,135,129,194, 83, +184, 27,120, 26, 82, 30,135, 7, 19,148,107,183,135,178, 29, 88, 63,175, 80, 40,252, 1, 60,113,248,240,225,101,124, 62,127,176, +143,143, 15,244,122,253,145,161, 67,135,190, 11, 32, 67, 46,151,235, 31,132, 10,176,101,135, 84,253,147,199, 21, 74, 41, 61,115, +230, 12,250,244,233,195,189,147, 28, 60, 82, 0, 60, 90,135,204, 38, 81,142, 43,121,142,137, 79, 60,149,247, 15, 28,208, 89,225, +169,167,158,146,238,217,179, 71,205, 86,102,112,112,240, 93, 55, 10, 11, 11,157, 7, 83, 40,149, 74,194,178,140,247, 76, 9,168, + 45,159,127, 99,201, 91,181,106,213,136, 45, 91,182, 36,103,103,103, 3, 0, 66, 66, 66,158, 77, 79, 79,223,238,109,251, 58,246, +123, 74,169,253,253, 96,174, 51,239,138,237, 58,113,163, 60,179,109, 7, 79,200,255,177, 51,103,206,108, 41, 43, 43,235,209,169, + 83, 39,220,190,125, 27, 85, 85, 85, 0, 48,120,203,150, 45, 42,127,127,255, 11, 10,133,226,121,185, 92, 94,231, 86,146,103,206, +156,241,200, 32, 72, 77, 77,149,202,229,114,181, 39,223, 81, 42,149, 42,153, 76, 38,245, 38, 1, 20,245, 48, 9,195,132, 9, 19, + 60,121, 63, 0, 0,157, 58, 89,119,192, 45, 47, 47, 71,117,181, 53, 13,186, 78,167,243,228,125,171, 19,167, 79,159,166,131, 7, + 15, 70,207,158, 61,225,227,227, 83, 84, 93, 93,253, 8, 55,140,254,243,224,156, 12,232,158, 37, 2,226,172,216,123,139,223, 19, + 70,187,125,230,249,153,187, 61,146,169, 82,221, 49,144,178,179,179,225,239,239,111, 31,132, 24,176,217,252, 67, 38,147, 81,165, + 82,233,124, 78,106,121,198,171,186,141,138,186,179,157,171, 43,249,245, 1, 33,132, 14, 27, 54, 76,154,146,146,226, 17, 89,108, +217,178, 37,185,117,235,214,120,249,229,151,161,213,106, 45,241,241,241,219, 86,172, 88, 49,105,225,194,133,155, 61,252,255,248, +227,143, 63,236,231,163, 71,143,198,238,221,187,235, 60,103, 35,214,169, 47,211,176,176, 48, 0,160, 14,153,225, 60, 34,255,210, +210,210,180,174, 93,187, 54, 3, 0,177, 88, 12, 95, 95, 95, 20, 21, 21,161,164,164, 4, 1, 1, 1, 40, 42, 42,234,177,123,247, +238, 12,133, 66,209, 93, 46,151,223,168, 75, 94,239,222,189, 33,147,201, 16, 18,114, 39,235,223,202,149, 43,107, 60, 19, 23, 23, + 7, 0, 56,122,244,168,202,155,126, 83,159,236,143,107,214,172,169,237,150,125,175, 2,111,225,239,239,143,115,231,206, 65, 40, + 20,194, 96, 48, 96,247,238,221,200,201,201,193,162, 69,245,219,113, 54, 48, 48,144, 15, 32,250,224,193,131,187,163,162,162,110, + 62,255,252,243,109,146,147,147,193,231,243, 91, 53,111,222,156, 15, 14,255,104,242,103,174, 57, 43, 1,127,155, 32,192,240,240, +112,201,253,182,184, 27, 19,193, 3,151,218, 63,222, 66,171,213,218, 45,126,157, 78,135,117,235,214,217, 63, 30, 12,180, 46,207, +199,143, 31, 79,101, 50, 25, 5, 64,157,159,241, 20, 7, 15, 30, 84,189,245,214, 91,232,210,165, 75,131,213, 95,231,206,157,201, +219,111,191, 13, 74, 41, 82, 82, 82, 84,158,182,123,118,118, 54, 70,143, 30,109, 1, 0,145, 72,196, 11, 13, 13, 69,124,124,252, +166, 86,173, 90,209,240,240,240, 49, 30, 88,156,247,170,139,144,176,176, 48,202,252,174,227,199,143, 51,251, 1, 48,237,194,218, +237,175,213,106,183,136, 68,162,102, 0, 48,123,246,108, 76,153, 50, 5, 34,145, 8,190,190,190, 16,139,197, 32,132,128,207,231, +163,180,180,180, 25,128,120,133, 66, 81,167,236,184,184, 56,132,132,132, 32, 47, 47,207,254,137,139,139,171,241,169, 15,100, 50, +153,212,246, 59,189, 30, 19,230,207,159,111,255, 56,142,151, 78,215, 45,108,229,117,234,212, 9,254,254,254, 88,188,120, 49,252, +253,253,177,109,219, 54, 84, 86, 86, 54, 8,249,219,222,101,170,213,106,255,111,234,212,169,232,214,173, 91,155,221,187,119,227, +230,205,155,184,122,245, 42, 74, 74, 74, 12,247,115,108, 82, 40, 20,146,130,130, 2,170, 80, 40, 36,174,238,229,228,228,208,139, + 23, 47,114, 9,232,238, 3,249,199,196,173, 64, 76,220,138, 90, 21,131,251,162, 0, 16, 23,168,235,186, 55, 72, 79, 79, 87, 53, +132, 18, 48,101,202,148,135, 70, 9,168, 47,244,122,253, 93, 86,191, 55,205,203,144,201,248,241,227,237, 86,126, 82, 82, 18,234, + 75,252,142,214,191, 82,169, 36,195,134, 13,147, 42,149,202, 26, 30,129,250, 32, 49, 49,145, 0, 32, 81, 81, 81, 82,103, 79, 3, +203, 65,215,100,243, 6,160,117,235,214, 88,186,116,105,213, 27,111,188, 97,200,203,203,219,185, 98,197,138,145,141,221,190, 14, +123, 0, 16,199,118,242,176, 93,158,200,201,201,233, 1, 0, 51,102,204, 64,105,105, 41,174, 93,187, 6,161, 80, 8,129, 64, 0, +129, 64, 0,161, 80, 8, 95, 95, 95, 84, 86, 86, 34, 57, 57,121, 50,128, 64,119, 66,243,242,242,160, 84, 42,237, 31, 71, 79,192, +202,149, 43,145,156,156,236,245,239, 86, 42,149,106,219, 20,128,170,129,222,229,218, 18,119,179, 30, 63, 47, 95,190,140,157, 59, +119, 98,233,210,165,232,212,169, 19, 90,182,108,137,148,148, 20, 44, 90,180, 8,254,254,254, 0, 0, 62,191, 94,134,122,187,233, +211,167, 79,252,207,127,254,131,244,244,116, 92,187,118, 13, 38,147,233,229, 22, 45, 90, 4, 2, 48,222,239,190, 23, 28, 28,140, +152,152, 24, 85,110,110, 46,117, 36,255,152,152, 24,213,163,143, 62, 10,179,217, 12, 14,247, 22,142,196,239,120,220, 24, 30, 0, +234,226, 83,215,245, 70, 83, 2,198,140, 25,211, 16, 74, 0,245,224,195, 26, 47,190,190,167,193, 26, 36, 59, 59, 27, 58,157,174, + 86, 55,255,145, 35, 71, 26, 66, 49,168, 55, 14, 30, 60,168,178, 41, 22, 72, 73, 73, 81, 19, 66,208,186,117,107, 85, 67,118, 78, +198,253,111,243, 4,212,137, 85,171, 86,141, 25, 50,100, 8, 5,128,248,248,120,209,247,223,127,143,151, 95,126,153,113,205,139, +255,250,235, 47,145,237,222,222,240,240,240,231,216,252,255,209,163, 71,227,233,167,159,182,187,247,153, 99,230,156, 57,102,233, +254, 7, 0,216,172,127, 87,237, 64,156,238,215,137,221,187,119, 47,107,217,178, 37, 0,224,226,197,139,200,207,207,199,137, 19, + 39, 96, 48, 24, 64, 8,129, 64, 32, 0, 33, 4,102,179, 25,122,189, 30, 91,183,110, 5,128,190,158,120,142,100, 50,153, 75,229, + 37, 47, 47,175, 94, 74,128,195,111,175,151, 55, 0, 13, 48, 85,106, 52, 26, 49, 96,192, 0,168,213,106, 92,190,124, 25, 3, 7, + 14,180,223, 83,171,213, 8, 10, 10,178, 43, 2, 94,160,253,244,233,211, 11,190,251,238, 59, 68, 71, 91, 55, 50,106,223,190, 61, +204,102,243,143, 0, 74,238, 55,241,200,229,114, 53,163,124,134,132,132,224,216,177, 99,148, 33,127, 70,249,235,222,189, 59,155, +241, 97, 16,128, 31, 96,221,243,172, 46,140, 5, 16, 3,160, 21, 71,251,247,185, 99,179, 98,195,251, 24, 4,104, 83, 2,164,233, +233,233,106,111,101,116,238,220, 25, 83,166, 76,193,207, 63,255,236,109, 76, 0, 1, 64,127,254,249,103,151, 55,119,237,218, 5, +219, 61,143,101, 31,189,244, 24, 34,186,156, 67, 97,230,226,122,213,147,227,156,127,114,114, 50,162,163,163, 17, 19, 19, 99, 39, +255,142, 29, 59, 54,132,210, 87, 47, 69, 32, 42, 42, 74,114,240,224, 65,220,190,125, 91,202, 92,147, 72, 36, 82,165, 82,169,138, +138,138,146,120, 58,111,239,230,127, 73,217, 40, 0, 91,182,108,217,201,204,253,235,116, 58,172, 92,185, 18, 21, 21, 21, 16, 10, +133,240,241,241,193,165, 75,151,176,116,233, 82,104,181, 90,196,199,199,255,182, 98,197,138,225, 11, 23, 46, 84,185, 33,217, 26, +202,128,187,152, 0, 22,117, 14, 55, 59, 0,218,167, 3,220,253,222,160,160,160,193,213,213,213, 48,153, 76, 56,114,228, 8,248, +124, 62, 12, 6, 3, 42, 43, 43, 97,177, 88,236,239,177,209,104, 68,117,117, 53,243, 78,247,118, 39,183, 54, 55,127, 92, 92,156, + 61, 30, 32, 36, 36, 4, 69, 69, 69,245, 86, 68, 29, 86, 5,176,237,139, 26, 0, 65,174,110,172, 94,189,218,171, 66,196,199,199, +227,173,183,222, 66,255,254,253,237, 30, 16, 38,125,118,255,254,253,145,149,149,133,214,173, 91,123, 35,186,211,244,233,211, 47, +127,247,221,119,142,227,103,240,181,107,215,174, 53, 38,177, 12, 28, 56,144, 48,164, 63,112,224, 64, 12, 28, 56, 80, 5, 0, 89, + 89, 89,232,209,163, 7,219,118, 56, 9,192, 23,192, 38, 0,147,224,180, 37,184, 13,175, 3,248,194,118,252, 46,128, 30,128,251, + 45,234,255,206, 96,118, 3, 92,183,114,161,221,242, 95,183,114,161,253,222,125, 87, 0,238, 55, 30, 20, 37, 96,202,148, 41,244, +221,119,223,189,203, 21,232, 13,249, 55,164,245, 15,192,165,245,207, 88,253, 66,161, 16, 55,110,220,104, 84,242,119,180,254, 29, + 3,186, 84, 42,149,163, 23,224,190, 7,108,102,103,103,227,229,151, 95,214, 3,240,243,247,247,199,123,239,189, 7,161, 80,104, +191, 63,109,218, 52, 0, 64, 96, 96, 32,198,141, 27,135,195,135, 15, 31,184,143,229, 36,142, 30,128,186,148,128,176,176, 48,231, +173, 98, 93, 42, 3, 6,131, 1, 26,141, 6, 85, 85, 85, 8, 8, 8,128,143,143, 15, 76, 38, 19, 40,165, 48,155,205, 48, 24, 12, + 48, 26,141, 48,155,205,142, 10,253,237,186, 10,153,151,151, 87, 35, 0,144,153, 14,112,244, 8, 56,222,175, 47,188, 8, 8, 20, +215,118,195, 49, 38,192, 19,101, 96,233,210,165, 24, 59,118, 44, 58,119,238, 12, 63, 63, 63, 72, 36, 18,104, 52, 26,248,251,251, + 67,171,213, 98,253,250,245,224,241, 60,118,200,118,152, 62,125,250,229,121,243,230, 97,219,182,109,120,238,185,231, 0,160, 45, +128,155, 15,194, 56, 44,151,203,213, 1, 1, 1,210,137, 19, 39,170, 0, 96,243,230,205,210, 73,147, 38,121,210, 22, 6, 0, 83, + 0,252, 92,135, 18,224, 56,213,246, 8,128, 62, 0, 50, 56,219, 30, 53,136,191, 54,252, 45, 51, 1,214,151,252, 25,120,107,165, + 59, 14,200,203,150, 45,171, 55,249, 51, 24,208,191, 31,246, 31, 80, 97,227, 1, 63,187, 82,112,244,210, 99,245,250,141, 97, 97, + 97,200,203,203, 67, 82, 82, 18, 58,118,236,136, 13, 27, 54,120,108,117, 41, 20, 9, 18, 7, 15, 78,131,144, 63, 51, 31, 95, 84, + 84, 36,117,190, 55,108,216, 48,105, 82, 82, 82,131,197, 2, 0, 86,247, 63, 91,239,147, 86,171, 61, 15,235,188,176,101,243,230, +205, 88,191,126, 61, 0, 96,211,166, 77,208,106,181,204, 99,166,172,172, 44,180,106,213, 56, 94, 73,167,104,255,187,148, 51,182, +251,196,231,229,229, 29, 49,155,205,208,106,181,184,125,251, 54,180, 90, 45,244,122, 61,244,122, 61, 42, 42, 42, 80, 86, 86,134, +210,210, 82, 84, 86, 86,162,186,186,154,153,219, 77,171, 75,166, 51,185,187, 10, 36,117, 94, 21,192, 22, 54, 87, 63,117,113,205, + 19,248, 53,116,123,108,216,176, 1, 18,137, 4,126,126,126, 56,119,238, 28,212,106, 53,252,253,253,241,254,251,239,227,240,225, +195, 88,180,104,145,167, 10, 64,219,233,211,167, 95,157, 52,105, 18,126,253,245, 87,134,252,219, 63, 40,228,111, 29, 23, 20, 18, +134,252, 1, 96,226,196,137,170, 11, 23, 46,120, 58,181,202, 40, 1,176, 41, 1,206,211, 1, 23, 29,142,243, 1,156,230,104,255, + 14,156,131, 0, 27, 69, 1,184, 31, 65,128, 13, 77,254, 54,226,110, 8,203,141, 44, 91,182,172, 94,228,255,226,235,123, 48,160, +255, 29,215,205,150, 95,183,218, 61, 2,251, 15,168,188, 82, 2,228,114, 57,108, 75,195,160,215,235,177,111,223, 62, 44, 93,106, + 93, 81,112,250,244,105,152, 76, 38, 15,100,197,170, 1,107,224, 31,165,148, 9, 6,172, 23,249, 51,214,127, 93,110,254,134,138, + 5, 96, 20, 9,137, 68, 34,117,247,108, 72, 72,200,168,248,248,248,176,244,244,116,193, 15, 63,252,192,187,112,225, 2,166, 77, +155,102, 98,234, 49, 62, 62, 30,233,233,233,248,225,135, 31, 4, 87,174, 92, 65,120,120,184, 91,153,247, 34, 6,128,177,164,157, +148, 0,202, 40,125,108, 17, 26, 26,154,105, 50,153, 96, 48, 24,112,235,214, 45,220,184,113, 3, 55,111,222,196,205,155, 55,113, +235,214, 45,104, 52, 26,232,245,122, 84, 87, 87,163,180,180,148,249,159, 5,117,201,100, 2,253, 28,149,208, 58,202,238, 17,249, + 51, 57, 0,156,175,213,167,127,184, 88, 13, 96, 87,242,216,202,200,201,201, 65, 86, 86, 22,244,122, 61, 34, 35, 35,209,183,111, + 95,108,216,176, 1,239,188,243, 14, 68, 34, 17,248,124, 62, 4, 2,214, 14,217, 14,211,167, 79,191, 62,105,210, 36,100,100,100, +224,131, 15, 62, 96,172,223,235,120, 64,150, 49,103,102,102, 82,102,206,255,196,137, 19, 88,183,110,157, 20, 0,186,119,239, 14, +199,192,192,122, 42, 1,115, 97,157,255, 31, 15, 96, 22,128,112,252,195,221,255,192,157, 72,127, 87, 65,128,206,171, 0,238,215, + 20, 0,245,240,250,223,133,252,237, 74, 64, 61,166, 18,106,144,191,171,243,253, 7, 60, 31,223, 28, 7, 93, 63, 63, 63,244,236, +217,179,198,253,244,244,116,143,228,141, 31, 63, 30, 73, 73, 73, 96, 20, 1, 0,212,118,205,227,117,231, 27, 54,108, 80, 1,192, +238,221,187,165,174, 34,214, 83, 82, 82,212,151, 47, 95,118,105, 61,186, 66,109, 73,127, 24, 69, 35, 37, 37, 5, 81, 81, 81, 82, +149, 74,229,182,239,164,167,167,239, 91,190,124,249,136,212,212,212,253,161,161,161,200,206,206,134, 86,171, 21, 4, 6, 6, 98, +250,244,233,208,104, 52, 87, 82, 83, 83, 59,133,134,134, 34, 53, 53,149,196,198,198,186, 83,142,239,154,243,175, 71, 12, 64,141, +119,139,201,151, 96,203,157, 96,247,204, 56,204,255,187,109,143,136,136,136,119,212,106,245, 28,179,217,140,178,178, 50, 24,141, + 70,251,188,127, 85, 85, 21, 40,165,160,148, 34, 43, 43, 11, 6,131, 1,209,209,209, 47,201,229,114,147,171,164, 35,181, 33, 58, + 58, 26,209,209,209, 53,130,254, 60,157, 2,112, 36,122,155,203,159, 58,246, 15,219,170,128,134, 30,215, 88,143,159,204, 82,191, + 55,222,120, 3,106,181, 26, 82,169, 20, 57, 57, 57,104,210,164, 9,242,243,243,193,231,243,217,122, 0,200,244,233,211,175, 78, +157, 58, 21,135, 14, 29,194,251,239,191, 15, 0,193, 0,174,225, 78,254,135, 70,183,252,153,241, 37, 47, 47, 15, 97, 97, 97, 76, + 63,147,198,196,196,168, 66, 66, 66,144,149,149, 69, 89, 6, 2, 58, 42, 1,147,108, 10,192, 38, 0, 71, 0,200, 1, 72, 0,220, + 0,135,134,235,192, 13,157,141,207, 85,192,207,202,149, 43,107,189,222,152,228,111, 91, 1,112, 47,180,104,175,101, 94, 45,112, +223,191,125,125, 61,243, 90,186, 11, 18,243, 20,209,209,209,210,164,164, 36,245,132, 9, 19,104, 98, 98, 98, 13, 69,192, 73,225, + 99, 93, 15,177,177,177,110, 53, 27, 15, 19, 3, 81, 39, 69,194, 58, 42, 73,165,172,200,223, 97, 48,183,207,235,135,135,135,255, + 43, 62, 62,254,199,113,227,198, 33, 43, 43, 11, 87,174, 92,233,180,120,241, 98,105,108,108, 44, 43,121,247, 40, 15, 64,141,122, +174,133,248, 88,101, 12,148,203,229,186,132,132,132, 37,187,118,237,250,208,100, 50,161,164,164,196, 30, 3, 0, 0,183,110,221, + 66, 73, 73, 9, 40,165,140,213,238, 17,203, 50,243,255, 97, 97, 97,246, 8,118,230, 58, 91, 37,192,133,149,127,215, 52,212, 61, + 32,127,143,193, 40, 1, 11, 23, 46, 68, 74, 74, 10,198,141, 27,135,229,203,151,227,205, 55,223,132, 64, 32,128, 88, 44,118, 59, +134, 80, 74, 45, 51,102,204,192,143, 63,254,136,239,191,255, 30, 0, 58,218,200,191,193, 13,170,250,160,176,176, 16, 59,119,238, +172,145,197,209,118, 44, 29, 62,124,184,202,203, 37,143,102,155, 18,176,195,102,253, 71,112,228, 95, 59, 92, 5, 1,178, 82, 0, + 60, 73,196,225, 45, 97, 55, 52, 26,130,252,235, 75,212,247, 2,115,231,206,149, 94,184,112,161, 65,101,218, 92,164, 13,186,148, +142, 33, 60,219,218,122,198, 43, 64, 9, 33,176, 88, 44,216,178,101, 11,107, 37,224,173,183,222, 98,202,121, 87, 12, 0,143,199, +131,197, 98,193,219,111,191,173, 98, 75,158,117,201, 75, 73, 73, 81, 59,102, 69,244,162,223,253,180,124,249,242, 91,169,169,169, +187,217, 90,253,247,193,219, 70,156,189, 61,181, 40,124,172,148,128,216,216,216,143, 20, 10, 69,210,207, 63,255,124, 86, 36, 18, +129, 89, 21, 96,177, 88,208,188,121,115,104,181, 90,200,100, 50, 68, 71, 71,251,201,229,114,183, 11,188,153,241,197, 49,248,239, +248,241,227,136,142,142,174, 49,158,184, 27,135,226,226,226,104, 94, 94,158,212,217,197,239,109, 26, 96, 71,184, 8,240, 51, 1, + 48,173, 94,189, 90,108,179, 70,121, 14, 31,143,148, 0,199,196, 63,179,102,205,178, 31,151,149,149,185, 29,155, 8, 33,100,250, +244,233,244,135, 31,126,120, 30,192,239, 15, 34,241,216,136,158,120,122,143,141,210,238,132,235, 15,195, 24,126,191,193,172, 2, +112, 69,252,172, 86, 1, 52, 52,169,215, 38,239, 65, 81, 30, 30,228,142,243,217,103,159,169, 27, 90,166,211, 26,233,123, 6, 39, +247, 63,219,151,154,109, 46,116,226,193,239,189,167,191,117,209,162, 69,123,234, 83,159,163, 71,143,174,177, 44,246,233,167,159, +174,225, 25,240,112,238,159,120,232,237, 97, 85,110,185, 92,126, 78,161, 80, 52,217,187,119,239, 39,249,249,249,115, 42, 43, 43, + 97, 54,155,209,175, 95, 63, 12, 28, 56, 48, 62, 58, 58, 58,142, 13,249, 3,192,209,163, 71,237,199, 81, 81, 81, 53,174, 59,159, +187, 25, 87,136,163, 66,203, 40, 19,182, 56, 0,175,218,125,194,132, 9,181,221, 18, 56,140,151,162,123, 53,174,184,241, 84, 88, + 0,224,251,239,191,231, 54, 76,225,192, 90, 9,168,141,252,107, 83, 0, 26,186,115,113,157,149, 3,241, 80,179,255,199,213,141, + 35,225,223,131,105,129, 6,121, 7,229,114,185, 14, 86,215,235, 92,230,218,249,243,231,217, 16,151, 29,189,123,247,110,240,241, +192,149, 66,235,173,203,255, 94, 43,139, 28, 56,254,184,159, 74,128,219,202,245,118, 31, 97, 14, 28, 56,112,224,192,129,195,195, + 11, 30, 87, 5, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56, 60,132, 48, +193,131,237,138, 57,255,124,202,173, 0, 0, 32, 0, 73, 68, 65, 84,252, 51, 33,224,170,128, 3, 7, 14, 28,184,177,157,195, 63, +188,147,156, 60,121,210,235,136, 75, 87,193,132,110,228,213,185,254,216, 11,121, 13, 93, 62, 78, 30, 39,239, 31, 45,239,207,119, +174,120, 61,176,244,255,164, 19,238,181,188,227,139,188,151, 23,182,252,110,121, 76,253, 41, 20, 10,137,209,104,196,165, 75,151, + 84, 6,131, 1, 2,129, 0, 5, 5, 5,120, 41,160, 51,246,100,102,162,242,241,142,136,136,136,144,242,249,124,102, 93,123,163, +181,175, 66,161,120, 12, 64,235,179,103,207,238,108,223,190, 61, 79,163,209,136,219,183,111,191,212,215,215,119,173, 92, 46,191, + 6, 0, 9, 9, 9,188,132,132, 4,115,109,242, 18, 18, 18,154,218,188, 5,250,216,216, 88, 10, 0,139,255,253,228, 55,242, 39, +243,167,111,204, 12,189, 36,104, 61, 42,162, 73,211,102, 21, 0, 40,165, 84, 0, 32, 48, 33, 33,225, 42,247,190, 61,216,242,238, +181,150,200,118,211, 23, 79, 83,224,122,156, 50,119,101,228, 83, 18, 65, 80,128, 42, 55,251,162,244, 81,159, 38, 88,112,230,160, +250, 65,210,178,234,200, 71,206, 45,113,105,100,140, 29, 59, 86,178,107,215, 46, 85,252, 59,214,243,223, 14, 61,137,131, 7, 15, +178,106,151,127, 77,123, 69,194, 35, 68,149,117,225, 2,180, 90, 45, 58,117,234,132, 38, 77,155, 98,107,210, 22,214,237, 58,126, +252,248, 26, 47,110, 82, 82, 82,157,123, 41,216,178, 43,122,213,111,152,141,154, 40,165,245,235,119, 50, 77,205, 87, 85, 25,228, +189,172,176,213, 64,200, 43,214,227,188,245,192,241, 5,245,111,212,241,183,107,150, 47,169, 37,171,175, 41, 20, 10,170,211,233, +164, 91,183,110, 85,229,229,229, 65, 38,108,129,182, 29, 91,161, 74, 87, 9, 95,189, 9, 67,222,124, 13,195,198, 77,196,142,239, + 18,176,125,255,126,213,168, 81,163,164, 15, 64, 23,206, 54,155,205,237,242,242,242, 44,125,251,246, 21,133,134,134,226,196,137, + 19,239, 84, 85, 85,141, 85, 40, 20,209,114,185, 92, 19, 27, 27,107,169,107, 73, 88,108,108,108,185,227,249, 87, 95,125,197,219, +253, 83, 92,183, 14, 51,250,227,237, 65,189, 90, 29,221,251,223,196, 45,167, 37, 39,187,245, 30,190,156, 16,162,145,203,229, 5, +253,250,245,179,216,148, 6,206,211,240, 15,115, 19,121,170,105,176,202, 54,230, 13,249,127, 29,245,172, 36,178, 85, 7, 21, 1, + 69, 78, 69, 9,218,181,239,172, 50, 90,204, 88,212,103, 48,138, 58,181,146,126,183,227,119, 86,138, 64,204, 36,208, 30, 93,153, + 51, 62,182,238,181,224,208, 49,138,152, 73, 64,143,174,192,130,101,245, 35,110,102,131,146,250,102, 39,115,165, 76, 52,148,220, +250,128, 82, 74,177,132,128,124, 84,231, 51,192, 18,130, 9,231,101, 15,204, 90,235, 59,228, 79,109,228, 63, 12,135, 15, 31,102, +245,221,180,163, 47, 82,147,177, 7,148,202,235, 72, 79,179, 38,172,201,190,144, 5, 0,216,185,147,208,172,139,227,165, 11,230, +178,107,151,145, 35, 71, 90,246,237,219,199, 75, 74, 74,194,129, 3, 7,106, 36,195,113,134,151, 41, 84,237,205,228,162, 35, 83, +234,133, 66,193,164, 11,175,119,206,130,144, 87,236, 27,237,172, 94,189,186, 97, 20, 0,135,122,178,237, 78,200, 10,185,185,185, + 80, 39, 38,170, 62,138,158,128,126, 83,102, 65,212, 38, 16, 16,216,146,253, 89, 40, 96, 17,194, 82, 77, 49,230,149, 24,228,127, +190, 2, 71,142, 28, 81, 41, 20,138, 26,233,110, 27, 1,102, 30,143,215,186,101,203,150, 80,171,213,130,190,125,251, 98,208,160, + 65,188, 27, 55,110,244, 63,117,234,212, 25,133, 66, 49, 64, 46,151,223,176,145, 53,143,101,221, 53, 25, 49,124,100,200,242, 85, +219,120,113,211, 78, 55,139, 24, 61, 83, 26, 17,158,252,228,155, 95, 20, 60, 19,250,196,203, 97, 0,202, 97,141, 49,224,213,198, + 15,142,137,173,220,245,163,122, 43,164, 28,156, 61, 9,238,188, 5,246, 99, 79,130, 0, 41,211,184,253, 94,238, 3,133, 66,193, +243,128, 8,157, 55,169,160, 97, 97, 97, 8, 11, 11,243, 58, 79,188, 98,114,140,100,114,255, 72, 85,247,118,193,232,218, 46, 24, +143,183,106,143, 96,223, 38, 16, 91,128, 46, 62, 77, 16,144,115, 77, 53,253,153,231, 36,108,100,245,232, 10, 92,200,229,225,252, + 69, 63,156,201,109,134,231, 71,250, 99,213,187,124,244,232, 74, 26,204, 72,175, 47, 73, 51,219,156,134,132,132,168, 50, 51, 51, +145,153,153,137, 15,127, 58,133, 71,199,196,169, 0, 80, 15,183, 60,165,108, 63, 50,153,204,253, 91,188,196, 90, 71, 97, 97, 97, +144,201,100, 46, 63,204, 51,158, 98, 92,223, 15, 36,142,229, 25,219,103,137,164, 33,218, 99,236,216,177,146,157, 59,119,170, 8, + 33,120,227, 19,130,223, 14, 13,195,161, 67,135, 88,125, 55, 49,113,138, 36, 34, 60, 22, 67,135, 94,199,231,159,127, 94,227,222, +228,201,192,152, 49,192,252, 57, 73,170, 85,159,177,107, 19,134,252,213,106, 53,120, 60, 30, 38, 78,156, 8, 62,159, 95, 31,178, +191,203,242,119, 53, 32, 19,226, 29,249, 55, 24,194, 86, 1, 0,214,172, 89,131, 53,107,214, 88,175, 13,136,111,180,226, 28, 56, +112, 0, 95,189, 16,131,129,207,201, 32,104, 17, 4, 34,228,131, 39,228,131, 47, 22,129,231, 43, 6, 64, 65,205, 38, 80,131, 1, +175,189, 50, 11,101,251, 51,145,155,155,171, 82, 40, 20, 18, 52, 30, 72,102,102,102,100,199,142, 29, 69, 22,139, 5, 41, 41, 41, +216,182,109, 27, 2, 2, 2, 16, 25, 25,217,110,243,230,205, 31,219,158, 99, 21, 16,168, 80, 40,248,135,247,255,242,191, 71,252, + 10,218,232,202,249,152,188,164, 2, 95,254,247, 51,160,105,111,193,127,227, 90,119,201, 61,241,243,100, 7,238,224,213,162, 24, + 18, 7, 82, 39,214,203,196,126,236,120,253, 30,237,133,193,161,129, 61, 0,246, 86,218,184,251,231,146,174,143,118,109, 46,255, +232, 53,139,135,236, 72,194,194,194, 40,147,150,212, 33, 61, 41,245, 52,109,167,226,133, 87, 36, 79,117,124, 84, 37,170, 50,193, +247,191,111,193,164, 55, 64,252,198, 50, 4,136,196,168, 18, 86, 66, 87, 85, 9, 95, 16, 84, 95, 45, 82,125,250,233,167,210,183, +223,126,187, 78,242,189,144, 11,172,219,100, 1,160,183,125,128, 39,159,224,225,133, 81,164,198,123, 19, 51, 9, 88,183,201, 43, +242,150, 42,149, 74,234,173,181,206, 88,253,153,153,153,119,234,224,176, 17,149, 6, 29, 0, 96, 68,220, 62, 40, 87,142,244,200, +203,144,187, 34, 23, 66,146,115,167, 35,144, 66,144,150, 61, 28,206,139,208,234,255, 94, 96,215,176, 31,217,243,205,147,218,210, +206, 18,155,210,119,252, 56,187,118,150, 63,251,165,100,221,182,127,171,182,159,250, 0,203,231,253,134,112, 73, 40, 54,126,125, + 8,223,238,181,110, 16, 52,243, 95, 31, 72,215,254,244,129, 87, 74, 85,252, 59,160,192, 78, 40,127, 56, 11, 74, 41,154,182,126, + 28,135, 14, 29,130,109,223,130, 58,203,183,234, 51,153, 68, 38,107,161, 2,190, 2,240, 27,210,211,129,240,240, 59,247, 63,254, +248,206,241,252, 57, 73, 42, 95,191,197,210,153,175, 45,173,179,156, 12,249, 71, 69, 69,193, 98,177,224,203, 47,191,108, 80, 7, + 13, 0, 88, 44,150,187,201,159,214,253,254,242, 38,104,107,188,252,204, 16,110,145,185,120,206,238,231,179, 30,244,237,123,247, + 28, 59,111,162,182,134,154,111,177, 76,195,188,121,243,236,247,231,205,155,135, 53,107,214,128,215,109,198,157,255,106,123,222, +149, 60,193, 68,215,229,115,222,201, 90, 48,145, 93,249,170,170,170,208,182, 83,103,192, 98, 0,207, 7, 32, 2, 62, 76,229,165, +168,202,187,132, 91, 5,133,232, 48, 88, 2, 34,106, 14, 98, 52, 0,124, 30, 86,206,124, 19, 35,215,125,128, 5, 11, 22, 52,244, +184,204,138, 21, 21, 10, 5,161,148, 54,175,172,172, 28, 28, 20, 20,132,172,172, 44, 88, 44, 22, 92,186,116, 9,235,215,175, 71, +207,158, 61, 17, 28, 28,252, 50,128,215,156,200,186, 86,111, 0,165,180,101, 39, 94,186,164,221, 35,163, 69, 37, 41,167, 81,170, +245,193,143, 59, 76,216,117,244, 39,204,145,249, 10, 4,122, 75,152, 45,166,192,165, 2,192, 17,122,227,163,182,233, 30, 87,158, + 1, 30,139,142,200,204, 27, 66,178,104, 24,214,165, 40,154,231, 94,204,197,201, 31, 78, 67,161, 80,120,100, 61, 48,228,160,215, +255, 12,189,126, 35, 52,154,104,198, 58,246,232, 7, 14,242,105,166,106, 93,101,134,120,201, 44,152,111,107, 96,186,120, 25, 2, +145, 16,126,132, 15,127,194,135, 63, 95,128, 32,161, 24,180, 92,135,235, 7,142,184,221,233,197, 21,169, 31, 58,102,177,191,135, +171,222, 37,136, 95, 76,108, 30, 1,239,172,127, 27, 57,171,224, 69, 10, 92,103,242,135,128,143,188,235, 21,184, 94,108, 64,250, + 57,235, 6, 34,221,166,109,135, 39,251,158, 11, 73, 14, 4,164, 16, 62,188, 83,214,191,173, 9, 2, 39, 95, 67,192,164, 51,240, +121,126, 9, 16,236,239,153, 39,151,197,206,109,158,108,241,170,216,246,186, 42, 34,232, 93, 28, 63,120, 9,255,111,252, 56, 4, +183,236,142, 89,255,126, 21, 95, 44,222,139,136,192,197, 88,251,211,135, 94,239,224, 67, 8, 16,187,224,140,221, 98, 25, 58,116, +168,141,144, 44,110, 27,120,202, 36,161, 10, 56, 0,224, 55,148,220,108,130,110,143, 52,193, 55,223, 88, 45,255, 37, 75,128,144, + 16,171,136,146,155, 77, 80,114,179, 9,250,245, 57,175,114, 71,254, 7, 14, 28,128,197, 98,177,147,244,230,205,155, 97, 54,155, + 61,114, 95,215,225,225,185,139,252,173,239,179,123,229,157, 2,100,173, 66, 33,101, 44, 53, 11,165,176, 88,238,238,190,204,117, + 11,165, 88,155,144, 32, 77,176,126,199,229,255,164, 0,161, 20, 36, 33, 65, 33,165,148,226,179,207, 62,179,223,103,142, 19, 18, + 18,164,148, 90,159,163, 0,169, 77, 94,130, 66, 1,219, 61, 98, 54,155, 97, 50,155, 97, 50,221, 93,103,204,117,147,217,140,175, +215,174,149,174, 77, 72,168,165,124, 20,130,166, 77, 1, 33, 31,102,125, 5,206,110, 73,194,251,175,202,209,225,117, 57,250,175, +248, 8,151,254, 60, 1,190,175, 24,198,226,155, 56,125, 84,141,237,135,246,160,244,198, 13,156, 57,115,166,193, 54,214,138,140, +140,100,229, 77, 80, 40, 20, 1,148,210, 65,153,153,153,191,191,247,222,123,189,206,158, 61, 43, 50, 24, 12,224,243,249,104,218, +180, 41, 76, 38, 19, 50, 50, 50, 64, 8, 17,185, 27,235, 19, 18, 18,252, 21, 10,133,111, 66, 66, 66,112, 73, 65,234,159, 31,254, + 47, 63,232,175, 67, 59,160,209,241, 32, 18,240,208, 33, 80,140,210,219, 34,200, 63, 53,225,244,237,254,254,238,120,195, 22,107, + 66, 29,251,162, 77, 49,184,235, 58, 71,215,247, 7, 12,249, 59, 43, 7, 60,119, 90, 40,179,223,119, 13, 55,231,232, 41,158,123, +251,108,238,126,189,126, 35, 0,130,170,170,239, 33, 62,118, 25,250, 61,143,214,184,239, 14,111, 15,136,146, 4,104,202, 97, 17, + 9, 96, 56,126, 22,213,231,243, 80,181,247, 16, 80, 89, 13, 17,165,240, 3, 31, 2, 16, 84, 91, 76,208, 84, 87,225,235,125, 59, +220,202, 92,245,174,213,186,119,132,245,156, 49, 87, 40,178, 46, 82, 44, 88,230,125,127,117,202, 87,206,218,101, 47,147,201,236, +123,107, 51,120,105, 77, 1,246, 31,215, 34,255,102, 21, 0, 32,255,102, 21,114, 10, 42,129,232, 68,102, 99, 20,247,174, 31, 82, +104, 85, 4,202, 79,195,223,255, 34,124,196,229,176, 88, 52, 48, 26,143,131,207, 15,129, 65, 87,220,104,157,117,194,232,127, 75, + 0,130, 47,127,155,129, 38,188, 71, 0, 0,215,179, 40, 6,140,227,227,223, 75, 71, 98,232,200, 94, 0,168,237, 57,207, 16, 21, + 21, 69,223,248,132,160, 73,171, 62,160, 0, 70,191, 48,147,245,188,255,218,111, 22,211,214,173,255, 2,112, 6, 37, 55,155,160, +188,216,186, 5,115,223,190, 64,183,110,192,203, 47,223, 33,255,242, 98, 95,148, 23,251, 34,200,239,122,157, 50,199,143, 31, 15, +169, 84,138,225,195,135,215,112,253, 59,126,188,153, 18,112,245,222,122,131, 88,135,249,109, 66,136,253, 83,219,181, 88,185, 92, + 45,143,113, 63, 39, 30, 19, 19,163,114,101, 57,207,155, 55, 15, 49, 49, 49, 53, 8,181, 54,121,191, 41, 20, 56,115,230,140,221, + 5,239, 88,103, 12,156,175,205,140,141, 85,199,202, 93,111,213, 44,162, 20, 60, 63, 31, 24,111, 92,129, 98,241, 98,172,215,149, + 64, 27, 21, 97,191,255,221, 79,235,241,193,155,175, 34,116,193, 75,248,232,244, 1, 36,106, 47, 97,228,179,207, 34, 36, 36,196, +227, 96, 64, 27,209,211,240,240,240, 26,125,248,232,209,163,170,186,182, 99, 87, 40, 20, 66,133, 66, 49,240,244,233,211,249, 41, + 41, 41,234, 55,222,120, 35,226,203, 47,191, 20, 87, 84, 84,216,183,105,174,170,170, 66,147, 38, 77,114, 38, 76,152,208,125,200, +144, 33,143,184, 81, 36,120,132,144, 78,167,211,182, 20,101,239, 89,112,121,193,162,248,118,219,151,180,199,249, 66, 1, 74, 43, +248,176, 16,160,184,194, 0,218,162,107,213,252,119,150,245,122,230,249,127,189, 6, 55,241, 4, 54,247,127, 13, 87,191,155, 99, + 14,141, 64,254,181, 77, 1, 80,182,174, 28,185, 92,238,238, 33,234,108,253, 91, 93,109,223,215,230, 29,112,251, 79,123,181,108, +163,210, 80, 35, 68,197, 26,136,127, 59, 0, 34,224, 1, 85, 6,208,114, 29,136,201, 4, 33, 0, 51,181,160,202,108, 66,185,201, + 0, 88,220, 91, 81, 76,144,223,170,119,107,213,105, 97, 13, 18,108, 16,133,149, 56, 4,242,185,125, 1,238,178,254, 1,252,242, +122,187, 26,231, 3, 23,230, 65, 72,111,195, 72, 90, 66,169, 84, 30, 96,251, 98,137, 43, 84, 8,250,232, 39,220,122, 35, 22,183, + 53,190,104,111, 60, 11,179, 57, 15, 0,112,229,100,219, 70,235,176,137,187,191, 80,189, 58, 74, 81,131,252, 25, 68, 4, 46,198, +224, 94,227, 17, 25,116, 22,137,187,151,170, 60, 25, 68,134, 13, 27, 70, 83, 82, 82, 80, 92, 60, 2, 45, 90,236, 71,147,150,189, + 65, 41, 5,143,199, 99, 21,136,148,159, 15,228,229,157,177,157, 85, 0,226, 10,104,116,192,160, 65,214, 43, 57, 57,192, 87, 95, + 1,229,101,128,174, 2,168,208, 1,254,129,101,172,202, 86,155,181,159,155,155, 11, 0,248,228,147, 79, 0, 0,161,161,161,247, +194,205,204,170, 14,231,206,157, 91,195, 98,119, 38,110,214,222, 29, 27, 97,219,231,253, 29,240,217,103,159, 97,205,154, 53, 80, + 40, 20, 18,119,193,117, 51,130, 67,145,125,246, 28, 10, 3, 3, 85, 60, 30, 15,115,230,204,185, 43, 38,195,147,242, 61, 89,221, + 28,212, 82,129, 87, 63,121, 23,125,198,143,135,226,147, 79,192,227,221,225, 57, 69,206,153, 59, 30,194, 67,135,176,111,223, 62, + 92,186,116, 73, 42,151,203,213,108, 54, 94,113, 36,255,180,180, 52, 21, 0,100,100,100,168, 34, 35, 35,165,105,105,105,234,240, +240,112, 73,122,122, 58, 34, 35, 35,165,149,149,149,170, 90,198, 92,227,180,105,211,250, 76,153, 50,165, 89,151, 46, 93,176,107, +215, 46,125,105,105,169,160,178,178,210,234,237,176,205,127,108,221,186, 53,116,244,232,209,190,114,185,188,210,133, 24,158, 3, + 89,243,242,178, 78,174,249,224,237,233, 77, 90,116, 83,226, 79,229, 43,248,235, 42, 65,254, 77, 1, 64,121,168, 54, 24,161,161, + 45, 10,103,207,152, 21, 65, 8, 41,100,198,124, 79,126,175, 11, 15, 1, 55, 85,240,128,160, 86, 45, 46, 37, 37,229,174, 79, 73, +161, 22, 37,133, 90,143,218,154,249,220,177, 98,173, 13, 47, 62,118, 25, 62,103, 10, 33, 40,208, 50, 30,128, 26,207,215, 38,240, + 92, 65, 62,142,221,190,134,179,151,242,112,243,210,101,148, 93, 46, 64,249,213, 66,152,244,149, 48, 26, 77, 40, 55, 27,160, 55, +155, 80, 77,205, 48,131,130, 18,246, 74,166, 99,180,255,133, 92,235,249,130,101,140,229,207, 67,252,187, 13,179,226,197,211, 56, +128, 56,165, 22,113, 74,109, 13,194,103, 62,145,113, 25, 16,210,219, 16, 80, 45,126,153, 97, 54,177,158, 2,184,121, 12,102, 93, + 19, 0,192,127, 5, 1,168,190,121, 5,153,159,182, 67,246,207, 99,113,236,211,126,200,201,186,214,168, 29,179,239,160, 16,232, +180,128, 78, 11,232,125,207, 1, 0,126,253,208,136,183,231, 45, 1, 0, 12,137,238,229,177,229,255,194,176,131,208,104,162, 17, +120,116, 63, 86,191,107, 85,114,135, 13, 27,198,202,245, 15, 0,203, 63, 94, 74,186,118, 5, 28, 63, 23, 46, 88,221,255, 0,208, +173, 27,197,154, 53, 64,167,238, 21,120, 44,226, 22, 6,141,184,133,231, 95, 50,178, 46,163,163,197,207,156,135,134,134, 34, 52, + 52, 20,115,230,204,105,232, 42,118,251,174, 57, 98,221,186,117, 82, 87,132,109,247,162,173, 90,133,117,235,214,177,178,132, 95, +123,237, 53, 21, 19,249,239, 10,243,231,207,191,203, 11,224, 10, 7,207,229, 99,250,140,217, 56,190,113, 35, 22, 45, 90, 84,171, +114,194,148,111,255,254,253,168, 43, 96,111,216, 99,143,224,251,239,190, 66,216,228,201, 88,190,124, 57,234, 42,227,188,121,243, + 48, 98,196, 8,120,179, 2, 32, 45, 45, 77,229, 16, 44,135,163, 71,143,170, 0, 32, 61, 61, 93, 69, 8, 65, 90, 90, 90,157, 50, +245,122,125,243, 29, 59,118,224,220,185,115,200,201,201,241,211,233,116, 48, 26,173,253,204, 96, 48, 96,247,238,221,196,166, 44, + 84,178, 40,142,165,186,186, 90,116,124,203,100, 84,101,127,129, 61, 41,185,184,116,157,143, 50, 29, 15,102, 10, 20,234,124, 49, +123,193,187,145,177,177,177, 5, 44, 12, 62,187, 94,193, 44, 57,101, 57, 29,192,161, 17,172,255,218, 20, 0, 2,128, 72, 36, 18, + 72, 36, 18,156, 58,117,202,254,201, 59,118, 5,165,149,165,104, 49,200,243,117,191,199,143, 31, 39, 0,224,231, 55, 5,226, 99, +151, 33,188, 82, 12, 74, 8, 68, 51,138,107,220,119, 75, 92, 34, 62,204, 20, 40,208,149, 32,191, 84,131, 91,101, 90,148, 86, 85, + 65,107,168,196,173,234, 74, 92,175,210,163,176,170, 2, 26, 99, 53,180, 22, 35, 12, 22,247,193,175, 79, 62,225, 98,192,115,136, + 11,120,117, 98, 19, 80,136, 64, 61,222, 6,252, 78,244,190,139,107,172,145,127,179, 10,251,143,107, 49,112, 97, 94,205,186,160, +183,225, 99,185, 2, 31,203, 21,124,240,148, 0,249,249,249, 6,182, 50,183, 92,178,160, 85,124,130,253,252,146,206,140,130,220, + 66,100,165,158,197,141,203, 37,141,222,113, 55,126,157, 2, 0, 40, 43,162,240,171,124, 12,146, 25, 2,252,191, 37, 66,251, 39, + 62,113, 50, 8,123,227,159, 62, 55, 52, 5,175, 44,176,146, 63, 33, 4,191,167, 90,155,128,237,154,127, 6,161, 61,186,215, 44, +231, 70,224,203, 47,129,139, 23,173,158,128, 15, 63,164,118,247, 59,165, 20,129,129,129,238, 71, 96, 91, 31,101,230,253, 63,249, +228, 19,228,230,230, 34, 59, 59, 27,217,217,217, 72, 78, 78,198,155,111,190,137,252,252,252, 70,107, 15,134,232, 92, 89,210,115, +231,206, 5, 33,132, 53, 25, 18, 66, 80,151, 50, 81,215, 61, 71, 28,242, 41, 1,225, 53,193,183,239, 44, 67,147, 29,201,136,137, +137,193,100, 70, 27, 3, 32,239,214, 27,115,195, 6,195,207,207, 15,195,134, 13,195,123,239,189,135,228,228,100,213,242,229,203, + 93,190,127,223, 21,102,227,122,175,199, 16, 28, 28, 44,181, 88, 44,117, 42, 20,117,221, 99, 65,142,118,143, 83,100,100,164,212, +129, 40, 17, 17, 17, 33,117,227, 61, 25, 62,108,216,176,102,249,249,249, 56,116,232, 16, 30,125,244, 81, 8, 4, 2,251, 20, 71, +112,112, 48,219,233, 8,139,237,255,146,174, 61,250,199,173,219,219, 28,127,237, 90,130, 39, 35,123,194, 95,204,131,191,159, 25, +190, 62,213,120,250,185, 9, 22, 0, 26,199, 47, 38, 36, 36,184,155,139,178,175, 2, 96, 57, 29,192,225, 65,243, 0, 0, 32, 10, +133,162,233,220,185,115, 49,119,238, 92, 0, 48,124, 28,251, 49,140, 69, 38,248,250,138,225, 77,227,201,100,214,240, 97,191,167, + 46,130,242,121,120,239, 87,189,163,245,207, 10,126,193,193, 82, 83, 19, 63,104,169, 25,231,116, 90,156, 41, 45,198,217,178,219, + 56, 91,166,193, 57,157, 6, 23,245, 90, 20, 87, 87,161,194,100,194, 53,189,206,254, 63,235,194, 11,163, 8, 86,189,203,199,170, +119,249,160,224,131, 18, 30, 98, 38, 17,188, 54, 73,132, 25, 19, 91,161,107,215, 54,176, 64,232,241, 79,102, 92,253,142,243,242, +117, 36, 5,170, 77,134, 52,167,192,170,200,103,174,176, 6,209,237,121, 43, 0, 0, 32,160, 90,240,169, 14,213, 60,107, 68,179, + 70,163,241,147,201,100,209,158,148, 49, 44, 44, 12,201,201,201,216, 88,161, 67,165,129,135, 87, 54,125,139, 34,177, 47, 42, 13, +141,183, 77,196,184,190, 31, 72,211, 52,203,176,241,199, 68,251,181, 95, 63, 52, 34, 34,112,177,253, 60,230,153,175,164, 20,172, +214, 15,211,213,139,129,105, 11, 70,160,249,209,100, 72, 63,141, 2,111, 44,160, 86,171,189,234,195,157, 58,213,140, 30, 31, 62, + 28,104,222, 28, 8, 9, 1,194,251, 54,133, 88,196, 7,159,119, 71,172,216,215,215,237,128,204,227,241,236,150,127,110,110,174, +221,234,103, 62, 31,125,244, 17, 62,250,232, 35, 92,187,198,222, 43,227,106,190,190,230,125,207,173,175,117,235,214, 73, 87,175, + 94,237,146,176,217, 90,255, 14,174,231,187,226, 20,152,115,139,133, 93, 10,123, 3, 33,176,232,171, 33,108,219, 9,242,165, 75, + 49,205,191, 57,154,171,211,236,247,103,252,107, 26, 62,248,239,183,200, 89,245, 11,222,239, 51, 28, 19, 2,187, 96,223,182,109, +200,203,203,115,249,254, 61, 31, 43, 71,175,222,189,165, 22, 91,153, 24,133,204,113,122,198,213,181,218, 48,115,230, 76, 74, 8, +161, 76, 96, 31, 51,223,239, 72,242,105,105,105,234,136,136, 8, 41,165, 20,204, 84,128,155,122, 75, 17, 10,133,143, 62,255,252, +243,185,165,165,165,208,106,181,240,245,245, 69,171, 86,173,208,188,121,115, 52,111,222,220, 93,229, 89,156, 20, 59,179,143,143, +143,254,197,216,207,165,235,143, 13,196,229,171,101,104, 19,192, 71,100,119,130,199,187, 80,248, 55,107, 86, 2,192, 92, 7,111, +112,251, 13, 60,164,214, 63,224,102, 25,160, 92, 46,175, 80, 40, 20, 62, 0,252,229,114,185, 93, 11,236, 16,213,222, 43,205,151, + 89,234, 39,147,201,168,104,134, 61,242,159, 56,204,255,187, 29,144,223,217,153,168,254, 36,250, 57,232, 77,213, 40,211,233,145, +107, 52, 66,104,177,126,185,212, 88, 5, 11,165,160, 0,118,221,188, 4,157,201, 8, 0, 44, 6, 38,130, 5,203,106,246,113,107, + 60,128, 5,102, 84,227,252,197,114,124,191,185,204,163, 31,235, 72,244, 54,151, 63,181, 29,219,137,157,205,234, 7,235,119,149, + 16,142,248, 26, 64, 8,138,139,239, 4,231,137, 44,215, 97,224,181,195,236, 62,217,184,126,221,110, 57,237,103, 83,190,216, 95, +215,213, 80,188,148, 74, 37,152,210,108, 58,125, 4,209,209,209,141,214,113,183,159,178, 46,239, 75, 77, 62, 11, 0, 24,220,203, +154, 25,239,237,121, 75,112,228,108, 47,252, 55,113, 50, 20, 59,102,177,158,255,127,101, 65, 52,130,130,146,109,103,106,155,178, + 20, 13, 74,173,214, 24, 64, 17, 20,148,204, 74,214,190, 61,123,237, 57, 45, 38, 79, 6,164, 82,130,219, 87, 3,160,211,138, 81, + 89, 38,194,166, 13, 4,115,231, 82, 92, 41, 42, 71,120,100, 4, 82, 14,168, 88, 89,197,102,179,217, 62,223,159,156,108, 45,171, + 35,225, 23, 21, 21,161,168,168,136, 53,255, 59, 16, 6,229,241,120,119,145, 42,165, 32,158, 38, 1,146,203,229,234,215, 94,123, +173, 70, 44, 0,227, 17,240,196, 21, 78, 28,180, 18,139,211,178, 2, 66,216,207,217, 17, 66, 96, 42, 47,135,176,101, 16,248,126, + 77,208,235,197,241,248,104,212, 72,188,195, 44,219,235, 63, 0,230,202, 42, 8, 91,180, 65,159, 8, 9, 58,119,232,130,207,207, +167,161,119,239,222,210, 99,199,142,221,165, 4,196,202,229, 0,136, 10, 0,102,197,198,218,151, 14,154,156,200, 94, 32,224, 3, +244,206, 66,197,218, 10,188,118,237, 90, 2,128,218, 92,252, 36, 35, 35,195,165,139, 63, 45, 45, 77,205,134,252, 19, 18, 18, 8, + 33,100,113,243,230,205,123, 69, 68, 68,116,189,112,225, 2, 78,156, 56, 1,179,217, 12,127,127,127,232,245,250,162,160,160,160, +203,158, 24,125, 10,133,130,215,166, 77,155,125,207, 61,247, 92,155,163,135, 51,176, 70,185, 15,205,136, 8,221,219, 84,227,226, +109,127, 12,237,110,188, 4,192,121, 30,203, 92, 87,155, 56,102,156, 34,132, 56,158, 58,231,125,225,208,200, 16,176,120,233, 13, + 0, 12, 14,131, 10, 45, 72,241,120,126,184, 6,185,215, 66,124,172, 51, 6,150,105,180, 82,163,159, 88, 85,202,179,224, 70, 85, + 5, 96, 52,194,108, 91,215,116,190,162, 4,133,250, 50, 80, 74, 97,203, 47,160,102, 83,188,152, 73, 4,235, 54,221,233,147, 23, +114,129, 30, 93, 77,224, 67, 87, 47,242,119,234,236,238,234,160, 86, 47,128, 82, 57, 75, 5,100, 66,163,209, 24,242,243,243, 5, + 43, 71,130, 23,183,111, 24,230,245, 62, 98,183,194,216, 42, 21,174,188, 46,206,231, 12, 9,177,181,230,176,132, 96,160,109, 37, +135,171,229,126,137,137,137,214, 76,128, 50, 25,101,147,243, 33,118,220,215, 82,197,246,217,170,180, 68,138,200,160,179, 24, 18, +221, 11,135,247,157,197, 81,237, 82, 16, 16,200,199,125, 37, 77,216, 62,155, 85,249,130,130,146, 65, 8,193, 11, 47,188,128,111, +190, 41, 3, 67, 49,214,191,148, 81, 8,104, 77,203,254,118,173,242,162,134, 75,165, 41, 7, 84,170,225,195, 1,195,141,142,184, + 90,226, 3,139,109,182,181,157,174, 13,222,138, 41,199,190,163,221,209,180, 67,119, 41,147, 37,176, 46, 48,196, 95, 80, 80, 0, + 0,184,113,227,134,221, 51,112,243,230, 77,251,192,234, 37,136,131,219,217,249,165, 36,108,242, 1, 56,226,155,111,190,145,174, + 89,179, 70,197, 40, 0,171, 87,175,246,216,250,119, 38, 12,111, 33, 22,139,113,227,202,101,116,233,218, 13, 22, 83, 53,136,201, + 12, 65,211,102,104, 58, 96, 32,154,244,127, 2, 22,157, 9,102,125, 53,168,201, 12,152, 45,136, 91,251, 95, 76,156, 60, 17, 98, +177,216,165, 60,211,166, 64, 86,255,215,213,115, 97,203, 93, 63, 27, 25, 25, 41,181, 41, 0,148, 82,138, 33, 67,134, 72, 83, 83, + 83,239,122,206, 29,249,219,234,202, 2, 96,119,247,238,221,251,127,241,197, 23,134, 91,183,110, 85,141, 28, 57,242,185,204,204, +204,247,245,122,125,113,203,150, 45,229,159,127,254,185,134,109,253, 41, 20, 10, 33,128, 71, 34,194,195, 91,197,206,136,197,165, +130, 75,154,169, 51, 98,159, 76,223,183, 33,254,122,185,102,240,192,168,145,150, 54, 29, 66,255,159,179,149, 95, 87,106, 97, 91, + 31, 35, 14,250, 39,113,193, 1,206,199, 28, 30, 84, 5,160, 46,235,194, 27,242,103,200,166,150,132, 49,172,148,128, 21, 39, 14, +170, 1,144, 73, 3, 34, 41,124,197,208, 82, 19, 12, 38, 19, 44,212,130, 22, 1, 1, 40,208,149,194,147,228, 66,174,150,247,221, +137, 1,240,108, 45,182, 43, 23,127,125,211,245,218,242, 8,140, 27, 56,112,224,246,184,184, 56, 81, 80, 80,144,229,250,245,235, +152,215,251,186, 51,249,179,254, 31,181, 37,236,241, 10,182, 44,127, 46,146, 60,221,245, 12, 91, 36,108,159,165, 6, 64,198,246, + 89, 34,217,121,250, 67, 85, 90, 34, 64, 64, 48,174,239, 7,210,237,167, 62, 80,179, 37,127,166, 47, 21, 23,143,160, 64, 25, 99, +253,194, 21,239,172,143,223,207,244, 7, 82,215,230, 26, 54,171,158, 20,107,123, 75,204,229,229, 42,194, 7,244, 85,190, 32,229, + 38, 8,120, 2,232,121, 98,233,168, 9,175, 98,118, 76,172,219,246, 72, 74, 74, 34, 73, 73, 73,244, 30,190,127,160,148, 18, 66, + 8,117,140,104,119,244, 4,120, 34, 75, 46,151,171, 99, 98, 98, 48,111,222, 60,187, 66,209, 88,169,112,135, 15, 31,142,217,137, +235,240, 81,121, 9,250, 69, 13, 5,175, 77,160,181, 76, 70,106, 77,221, 11, 33, 8, 95, 0, 34,226,227,155,132, 85,104, 54, 98, + 32,186,118,237,234,113,212,126,125,224, 96,221,171,194,195,195,165,169,169,169,245,170,171,220,220,220,232,253,251,247, 95,225, +243,249,219,158,124,242,201,143,103,205,154,117,107,237,218,181, 41,128,117,202,193, 3, 81, 60, 0,201, 39, 78,156, 24,244,195, +250, 13, 60, 17,223,231,234,248,151,198,247,157, 61,123,182,246,235,175,191, 30, 11, 32,192, 70,252,229,204, 6, 65,108, 60, 10, + 28, 30, 12,176,113,255,123,171, 0,212, 91, 97,112, 67, 62,172, 7,164, 77, 39,210,136,108,188, 76, 98,201,202, 81,233,170, 13, + 48,153,205,232, 58,104, 0, 66, 77,225,158, 18,110,131, 5,163, 48, 73,127, 0,168, 24,107,220, 22, 7, 80,175, 28,248, 74,165, +114,135, 66,161, 16, 36, 39, 39, 47, 88,185,114,229,167, 14,202,197,112,199,255,197,214,163, 0,160,193,146,151, 76, 56,207,196, + 89,212,254,251, 38,156,151,121,165,233,239, 60,253,161,154,105, 31, 10,138,237,167, 62,240,170,140, 86,114, 39,120,101,193,240, + 59,102, 47,185,115,111,193, 50,207,243,145,199,189,117, 70, 29, 7,144,181,223, 44,150, 84,234,173,251, 0,220,201,255, 31,235, +241, 59, 98,179,200,204,114,185,188,193,231, 85, 25, 37,160, 33,100,217, 98, 1, 84,204,113, 3,148,205,171,239,117,237,218, 21, +109,231,204,145,174,217,187, 87,149,247,241,111,144, 9, 91,160,185,109,243,158, 74,189, 9,115,223, 92, 4,190, 95, 16,118,109, + 80,224, 84, 75,130, 81,131, 7,123,157,183,223,108, 54,121, 61, 76,176,117,241,179, 80,190,200,243,207, 63,127,139, 82, 26,223, +163, 71,143,255, 21, 23, 23,235,188, 32,126,199,122, 31,150,145,145, 1,139,137, 96,240,144,190, 31,204,158, 61, 91, 11, 0,179, +102,205,178, 0,208,214,167, 73, 29, 60, 78, 53,142, 93,120, 69, 57, 60,100, 30,128,123,162, 20,120, 77,140, 73, 53, 18,236, 32, + 35, 55,171,209, 43,213, 41,233, 15,115,173,222,114,229,114,185, 25,192,127,108, 31,175,229,186, 42, 95, 61,127, 47,105,136,103, +238, 37,172, 4, 79,177, 96, 89,114,131,203,118,151,234,215,131,246, 53,222,203, 58,104,168, 77, 87,228,114,185, 90, 46,151, 55, +136, 44, 82,143, 57, 0,166, 12, 10,133, 2,182,237,123,145,239,176,125,111,234,254,125,246,237,123, 71, 68,140,128, 77,233,173, +245,255,241, 39,106,137,121,115,224,221,196,196,114, 55, 65,119, 74, 64, 67,212,215, 19, 79, 60, 81,109, 50,153, 82, 0,232,222, +123,239,189,122,145,104,108,108, 44,121,239,189,247,168,193, 96, 0,128,189,181, 61,183, 98,197, 10,178,112,225, 66,251,255,178, +165, 2,174,115,108,119, 14,238,228,112,127,193,214,195, 69,188,221, 71,152, 3, 7, 14, 28, 56, 52, 10, 76, 0,170, 0,136, 27, +216,136,115,183, 99, 32,235, 29, 5, 57, 60, 28,224, 26,147, 3, 7, 14, 28, 30, 46, 8, 0, 52, 97, 65,254,122, 88, 3,184, 27, +138, 15, 44,224,150,253,253,237, 58, 18, 7, 14, 28, 56,112,248,251,193,143,227, 11, 14,156, 7,128, 3, 7, 14, 28, 56,112,224, +192, 41, 0, 28, 56,112,224,192,129,195, 63, 29, 53, 92, 58, 39, 79,158,244, 58, 34,215, 85, 48,225,131, 46, 47,100,128, 15,124, +125,110, 64, 40, 42,129,197, 98, 93, 22,198,231,243,192, 35,124,235, 95, 30, 1, 33, 60, 80, 34, 0, 33, 4, 60,152,176,125,167, + 16,148, 82, 4,241, 90,192,147,242,217, 50, 42,182,132, 53,128,167, 28,214, 4, 3, 70,102,201,215,195, 88,127,156, 60, 78, 30, + 39,143,147,199,201,123, 48,229,113, 30, 0, 55, 56,120,248, 34,180,165, 90, 24,141, 20,183,110, 19,236, 73,246,197,222,125,254, +224, 17, 33,246,169,218, 98,239,129,118,216,171,106,135, 67,199, 90, 65, 0, 1,120, 16, 99,104, 36, 15, 62, 34, 31,214,255, 99, +210, 43, 83,233,164, 87,166,210,195,169,170, 42, 35,143,164,158, 61,147,121, 80,117,228,176, 46, 57, 57,185, 10, 64, 83, 78, 7, +125,248, 49,242,169,161,146, 89,179,166, 82, 79, 55,121,122, 88,161, 80, 40, 36,212,134,186,118,215, 99, 11,234, 4,174, 71,113, +224,208, 8, 30, 0, 6,131,135, 12, 98,253, 18, 30, 73,205,112,171,181, 52,180,188,134, 68, 70,166, 16,163, 71,154,113,234, 47, + 95,136,132, 2, 8,248, 2, 8,133, 20, 62,124, 35, 32,104, 10, 1, 42, 49,168,151, 9, 98,145, 15, 40,128,118,109,128,103,199, + 88,176,127, 27, 59,242,191,120, 62, 27,143, 62,214, 21,237,131,155,163,224,202,133, 78, 1,109,187,160,101,123, 51,254,248,253, +119, 36, 39, 39,151,160,145,119,196,146,201,100, 99,148, 74,229, 78,135,243,103, 28,207, 57,212,142,217,179,100,212, 84,117, 86, + 58, 40, 44, 80,101,177, 20,163,180,125,165,170, 67,219, 17,168,168,110,135,111,214,253,244,183,221,233, 44, 38, 38, 70, 53,111, +222, 60, 16, 66,176,122,245,106, 85, 67,228, 4, 96,210, 1,112,252,127,255,225,145,210, 69, 41, 8,143, 87, 87,123, 83,199,246, +100,218,244, 78,242,173,154,237,236,184, 51, 34,135,134, 5,147, 13,208,193, 75,192, 78, 1,104, 44,240,238, 51, 23,142, 25,101, + 4, 5, 31, 2,190, 16,131,195, 9, 90,183,226, 65, 32,224,193, 71,200, 71,143, 80, 30,174, 92, 53, 97, 80, 24, 15, 45,130,196, +248,227, 64, 51, 0, 0,159, 86,130, 82, 11,220,165, 8,158,244,202, 84,250, 87,102, 38, 58,183,239,128,191,210,142, 34,221, 96, +132,246,182, 22, 34,159,166,232,217,127, 8,250, 14, 25, 5,213,118, 37,100, 44,115,227,223, 3,226, 31,174, 84, 42,247,135,132, +132, 32, 51, 51,147,233, 48, 37, 0,230, 40,149,202, 29, 50,153, 44, 90,169, 84,238,255,187,189, 20, 51, 99,101,212, 71,160,129, +128,103, 64, 85,149, 25,165, 58, 95,252,248,243,126,143,234,127,196,200, 33,146,102,190, 26, 12, 31, 34, 66,231, 78,207,170,154, + 53, 11,128,209,100,194,173, 91,183,209, 38,255, 42,114,114,243,240,202,203, 99,232,134, 31,118,121,213,174, 97,182, 61, 21, 0, +246,219,100,223, 79,235, 31,184,179, 29,238,234,213,171,161, 80, 40, 36,141,149, 14,248, 62,190, 47,116,203,150, 45,119,239,167, +208, 72,228,165, 80, 36, 72, 8, 8, 98, 26,160,222,105,254,175, 32,233,175, 58,114,188, 45, 75,166,125,223, 43, 59, 94, 77,208, +185, 85,228,254,248,227, 15,251,249,232,209,163,177,123,247,238, 58,207, 57,220,123,242,119,188,230,168, 8,212,169, 0,164, 30, + 78,199,144,161,225,247,173,208, 22,207,178, 67, 58, 62,236,213, 75,200, 19,240,161,213, 8,208,182,181, 16,109, 91,139, 80, 81, + 33,132, 88, 40,128, 89,224,131, 1,125, 8,250, 61,206, 7,143, 8, 65, 8,129,143, 80, 4, 33,175, 26, 68, 44,130, 73, 15,152, +160,171,147,252, 15, 31,216,143, 46,237, 90,225,204,169, 51,200, 47,186,126,167,124,229, 21, 16,159, 61, 70,121,124,130, 1, 97, + 3,240,199,110,207, 56,118,237,218,181,146,204,204, 76,213,197,139, 23,225,235,235, 11, 95, 95, 95,233,214,173, 91,213, 30, 14, +102, 82,165, 82,185,159, 33,126,135,206,209, 28,192,168,111,191,253,246,246,171,175,190,154, 44,147,201, 70, 42,149,202,228, 7, +177,131,135,135,135, 75,210,211,211, 89,255,110,201,240,193,146,222,161, 77, 85, 29,218, 21, 33,160,153, 15,120, 60, 63, 84, 86, +154, 80,172,169,196,100, 89, 79, 42,110, 54, 0,223,127,247, 51,171,126, 36,196, 13,188,240,204,227,170, 94,189,122,226,250, 13, + 45,142,255,121, 2, 21, 21, 58, 4, 4, 52, 69, 72, 72, 39,240,248, 66,152,205,249,136,157, 57,149, 38,172,253,241,111,101,221, +196,196,196,168,230,207,159,111, 63,159, 55,111, 94,131,121, 1, 30,100, 15,128, 82,169, 36, 50,153,140, 38, 37, 37,193,213,198, + 74,247,219,104,151,203, 99, 65, 8,193,186,117, 10,105, 76, 76,253,148, 0, 94,167, 23,237,228,157,177,188,137,203,193,180,109, +115, 30,130,131,120, 15,109,251,253, 83,225, 72,246,174,148, 2,183, 30,128,212,195,233, 0, 80,111, 69,224,240,156,156, 58,239, + 15,253,188,155,215,131,133, 67,142,115,143, 6,161,100,117,107, 8, 5, 66,116,108, 95,129,242,114, 33,142,159,233, 8, 62,159, + 15, 62,225, 67, 36, 52,161, 87, 55, 61,186,119,227,131,128, 7,145,208, 7, 34, 62, 65,216,227, 6, 4, 5, 90,176,241,127,117, +203,238,217,165, 13,174,228, 22,213, 36,127, 27,242,175, 93, 33,132, 39,160,237, 34, 31, 71, 96,243,166, 40,209,222,102, 85,222, + 53,107,214, 72, 86,172, 88,161,186,114,229,138,227,101,213,152, 49, 99,176,107, 23,123,107, 83,169, 84, 30,112, 36,127, 23,104, + 25, 31, 31, 95,242,198, 27,111,236, 67, 35, 79, 81,212, 65,254, 42, 79,202, 22, 26, 18,164, 10,110, 83,134,150, 45,252,209, 33, +184, 45,252,252,253,112,229, 74, 33,204,102, 11,130,219, 55,197,217,243,105,136, 28, 58, 72,146,118, 56,163,206,193,244,245,215, +167,210,199, 67,181,120,228,145, 14, 56,119,254, 10,142, 31, 63,143, 91,183,203, 65, 41, 16, 24,232, 11,189,190, 2,253,251,247, + 66, 73, 73, 41, 10,143,255,137, 33, 79,134, 75, 82, 15,177, 87, 84,107,134, 60,189, 0, 0, 32, 0, 73, 68, 65, 84, 30,100, 48, +214,191,109,219,105, 48,158,128, 53,107,214,120,236, 5, 96,166,251,157, 51, 1,187,216, 78,182,222,253,175, 67,135, 14,180, 99, +199,142,245,206,197,175, 84, 42,201,132, 9, 19,104, 98, 98, 34,152,141,149,234, 34, 60,219, 86,184,119,149, 63, 50, 50, 82,194, +108, 14, 84,139, 18, 75,221,200,180,255,111,185, 60, 86, 85,159,119,212, 89,222,160, 69, 21, 56,182,188, 73, 13,226,231,240,112, + 90,255,206, 46,255,122, 77, 1,212, 87, 17, 24,250,121,183, 90,149, 0,111,200,159, 65, 74, 74, 10, 10, 11, 11, 1, 0,193,193, +193,212,147,151,129, 79, 43, 33, 32,102,136,132, 66,252,121,166, 21,248, 2, 1,154, 10,117,214, 56,128, 38, 60, 20, 22, 54,197, +227,189, 44, 32,132, 64,246,172, 9,212,194, 3,136, 15, 8, 40,172,129,252,174,161, 47,185,138, 27,154, 10,100, 23, 22,214, 90, +150,146, 82, 13,180,183,110,216,100,177, 30,128,156,201, 31, 0,176,107,215, 46, 60,245,212, 83,146, 61,123,246,184, 29,224,100, + 50,217,240,188,188, 60,151, 29,166,180,180,212,241,114,243, 37, 75,150,224,220,185,115, 35, 30,164,169, 0, 7,242,103, 13,201, +240,193, 18,177,224, 58,124,125,155, 67,236, 35, 66,151, 46,157,209,177,115,103,148,149,169,161,209, 84, 64, 36,226, 35, 40, 80, + 12,129,111,115,183,131,169,128, 22,162,105,147, 22,208, 87,154,112,230, 76, 14,174,221, 40,197,245, 27, 21,168,172, 22,227,145, + 96, 19,196, 62,124,228,100,231,225,209,174, 93,113,237,122, 25, 42, 77,205, 88, 13,208,142,110,255,218,174,123, 58, 29, 80,155, + 76,111,100, 49,214,255,188,121,243,238,186, 62,127,254,124,175,188, 0,174,118, 39,116,158, 59,110, 40,175, 66, 90, 90,154,170, +190, 27,242, 76,152, 48,129, 42,149, 74,200,100, 50,184,154, 14, 96,227,169, 98,200, 31, 0, 50, 50, 50,238, 42,147,237,190, 91, +163,135,217, 97,176,161, 60, 46,137,243,253, 49, 97,181,206, 37,241, 7, 7,241,108,163, 20,187,230, 29, 61,122,116, 13, 47,201, +211, 79, 63, 93,163,174, 56,183,255,131, 3,143, 99, 0, 26,202, 35,208,144,200,201,177, 42, 22,133,133,133, 30, 41, 1, 2,129, + 0, 66,190, 16, 66, 33,193,176, 33,128, 94, 87,141, 75,185, 34, 8, 5, 66, 8,204, 2, 68,132, 83,136,132, 66,240,249, 60,128, + 18,104,180,192,177, 19, 2, 88, 44, 22, 0,183,106,149,123,226,207, 92, 84, 84,212,158,129,179, 75,219,182, 84,103, 34,168,172, + 44,133,217, 98, 98,253, 59, 79,156, 56, 81,187,210,161,215,179, 34, 26,103,215,191, 43,205,112,251,246,237,142,207, 39, 55,134, + 23,192,149,139,223,145,252,109, 3, 32, 59, 11, 48,184,141,138,199,187, 10,147,217, 2,131,209,132, 91,183, 53, 16,138,196,168, +174, 54,194,104, 50,195,100,178,192,100,166,172, 60, 49, 34,161, 14, 98,223, 14, 40, 46, 46, 69, 89,185, 30, 26,109, 37,154,181, +232,139,193,143, 63,142,140,212,221,104,111, 48,161,180,172, 20,221,187,119,133,143, 72, 0, 93,185,230,111, 49, 80,216, 34,255, +237,115,255, 78,158, 41,175, 98, 1,230,205,155, 87,195,155,224,124,143,173, 2,160,209, 68,219, 31,140,141, 13, 66, 98, 98, 98, +141,254,202, 24, 8,249,249,249, 94,239,202, 41,147,201,104, 98, 98,162,125,155,241,218, 98, 2,156,201,213,217, 83,149,150,150, +166, 98, 2,223, 40,165,244,232,209,163, 53,238, 31, 61,122, 84,229,206,233,193, 40, 13,140, 18,224,104,197,215,102,232,187,249, +109, 24, 31,153,140,205, 0, 38,174,214,225,137, 69, 21,245, 82,190,156,231,248,221,197, 4,112,184,247,222,128,218, 60, 0,247, +213,191,227,202,210,175,143,245,239,100,177, 34, 39, 39,135, 25, 80, 88,245, 94, 62, 95,128,136, 65, 22,240,121, 2, 28,203, 20, + 35, 43, 71,140,177, 79, 1,207, 60, 13,140, 27, 77,208,174,141, 8, 98,145, 15,196, 34, 31,248,138,125, 16,220,206, 7, 98,145, + 24, 98, 55,203, 0, 11,242,175,146, 18,205, 77, 82,219, 64,210,181, 75, 39, 4, 52,247,135,216, 98, 64,133,222,120,223, 59,197, +225,195,135,247, 31, 62,124,184, 6,225, 59,126, 0,160,184,184, 24,227,198,141,107, 52, 43,223,102, 29, 73,156,175,217,142, 61, +178,228,204,102, 64,167, 55, 66,167, 51,160,172,172, 26, 55,111,106,113,237,218,109,148,151, 87,163,162,194,136,138, 10, 3,116, + 58, 35, 74, 75, 74,221,202,170,174, 54,161,170,202, 12,163,209,128,166, 77, 69,232, 24,220, 12,126,254,254, 0,128,144,174,157, +209,161,125, 51, 4, 52, 19,131, 82, 51,140, 38, 11,170,171,117,127,139,129, 36, 38, 38, 70,181, 96,193,130, 58,201, 60, 38, 38, +134,181, 69,106,219, 82,184,214,251,171, 87,175,198, 55,223,124,227,241, 86,195, 14,219,206,218, 63, 12,161, 22, 22, 22, 50,187, +103,122,196,110, 19, 38, 76,160, 73, 73, 73,112, 84, 30,148, 74, 37, 25, 63,126,124,157,223,155, 57,115, 38, 8, 33, 96,250,113, +120,120,184, 4, 0, 34, 34, 34,164, 12,145, 51, 86, 63,115,159, 82,106,191,207,226,215,214,176,226, 93, 41, 14,108,102, 80, 90, +182,108, 9,226,160, 37,212, 87, 30,135, 7,143,252, 93,157,123,229, 1,120,144, 44,255, 59, 3,188, 25,124, 62,223,227,239, 13, + 25,100, 65,235, 86, 62, 40, 43, 19,192, 71, 96,130,143,136, 15,117,186, 8, 99,165, 66,136,132, 66,148,149, 9,145,154,233,143, +102, 98, 2, 30,143,135,209,209, 6, 60, 55,150,130,199,163, 88,122,210,243,114,202,100, 50,202,247, 19, 67, 35,108, 9, 63, 99, + 1, 46, 22, 82, 12,151, 12, 99,189,165,111,255,254,253,113,228,200, 17,151,247,252,252,252, 88, 15,150, 90,173,118, 4, 0,172, + 95,191, 30,211,166, 77,179, 95, 47, 46, 46,182, 31, 79,155, 54, 13, 69, 69, 69,141,210,158,233,233,233,106, 66, 8,152,121, 82, + 30,143, 7,198,221, 89,199,188,105,173,200,191,122, 77,218,170,153, 94,229, 35,226,195, 96,180,160,170,186, 0, 87, 11,138,161, +209,150, 65,163,209,163, 88, 83,137, 98, 77, 37,154, 7,117, 6,144, 91,167,172,155,183, 41,110,220,188,141,158, 61,187,162, 68, +171,133, 80,192, 67, 89,121, 1,116, 37, 22, 60,246,168, 14,109, 90,181,130,159,159, 31,124,124,124,113,253, 70, 57, 8, 63,144, + 85, 25, 29, 93,242, 13,181, 10,160,161, 87, 16,212,102,173, 3,119, 98, 1,216, 66, 46,151,171, 99, 98, 98, 48,119,238,220,187, +188, 10,204, 52,131,183, 43, 11, 38, 76,152, 80,195,130,101,222, 47, 66, 8, 94,124,241, 69, 36, 37, 37, 17,182, 74,128,179,229, +239,120,207,217,211,224,140,181,107,215, 18, 0,118, 43, 63, 35, 35, 67,101,235,215,106,155, 55,128,249,171, 2, 64,210,211,211, +237,247,235,218,206, 53, 45, 45, 77, 53,100,200, 96,233,145, 35,214,119, 98,230,204,153, 56,121,242, 79, 41, 67,225, 71,143, 30, + 85, 49,191, 63, 34, 34,194,173,167,108,237,218,181,248, 74, 26,136,137,107,244,214,223, 53,223,191,198,253,137,107,244,246,250, +156, 46, 21,226,187, 3, 6,112,120, 8,148,246,184, 21, 53,149,238,149, 11,113,242,228, 73,246,171, 0,238, 5,241, 59,198, 2, +212,199,250,175,105,201,215, 36,127,155,155,201,237, 84, 64,203,150,124,240, 8, 31,173, 90,242,209,173, 43,197,181,107, 2,240, +248, 4, 66,129, 0, 66,129, 16,127,157,246, 71,144,191, 16,124, 62, 31, 67,194,205,240,245,245,129,197, 66, 1,106,246,138,252, +155,180,233,136,155, 21, 20,186,139,106, 8, 8, 31, 23,175,229,147,139, 44,201,223, 54,176, 73,175, 94,189,170,186,122,245,170, +171,223,171,102, 89,142,145,197,197,197,251, 24,146, 7,128,113,227,198, 97,253,250,245,246,103,202,202,202, 80, 84, 84,132, 29, + 59,118, 48,203, 5,239,123,231,181, 13, 92,170,140,140, 12, 21, 19, 44,102,187,230, 49, 41,164, 30, 74, 87, 75, 37, 97,160,133, +101,208, 87, 26,161,245,169, 2,133, 22, 85, 85, 38,148,149, 85,163,232,182, 30,215,174, 87,224, 73,105, 39, 0,169,117,202,170, + 52,180, 68,222,165, 91, 8,233,242, 8,186,116,233,128,226,226,219, 8,108,110, 70,183,110, 1,104,221, 42, 4, 98, 95, 95,148, +148, 84,224,248,137, 11, 40, 40, 44, 67,219, 14,189, 30,218, 1, 36, 65,161,160,132, 64,202,112,169, 35,169,214,181,110, 63, 65, +161,144, 36,172, 93,203,202, 11,176,102,205, 26,149,179, 2,176,106,213, 42,172, 91,183, 78,234, 78, 94, 66, 66, 2,141,141,141, + 37,114,121,160, 67,153,168, 43, 98,166, 0, 48,126,252,120, 86,238,127,199, 41,133, 22, 45,146,224,237,180, 1, 99,229,219, 20, + 0, 74, 41,197,144, 33, 67,164,169,169,169,181,222,119, 71,216,204,220,122,106,234, 17, 21, 33, 4,132, 16,244,235,215, 87,186, +118,237, 90,245,221,207,222, 81, 50,220,201,227, 77,208,130,145, 39, 27,222,185,134,126, 52, 97,245, 57,187, 60, 54,224, 98, 0, + 30, 30,184, 85, 0, 30, 68,139,159,193,164, 73,147,234,245,125, 30,143, 7, 62,223,250,233, 25,202, 67,255, 62,102,248,136,196, + 86, 5, 64, 40,196,224,112,192,199, 7, 16,242,125,208,178,165, 24,124,190, 14,102,179, 5, 22,139,231,110,123,189,230, 6,196, + 29,122,224, 82,242, 79,104, 37,224,225,112,254, 21,143, 7,148,121,243,230,169,215,174, 93, 43,173,207, 50, 64,102, 89,223,235, +175,191,110,191,198, 88,250,101,101,101,208,235,245,152, 62,125, 58, 0,224,235,175,191, 6, 0, 85, 99,180,109, 90, 90,154,218, +102,237,171, 0, 96,208,160, 65,245, 10,224,234,208,169, 59, 50,143,238, 65,235,150,126,240,243,179,118,251,234,106, 51,202,202, + 13,208,104, 43,209,177, 75, 47,252,184, 97,163,219, 54,249,253,247,189,228,197,231, 35,232,209,140,179,120,114, 72, 95,116,234, +212, 9, 70, 67, 21,250,247,123, 28,254, 1, 1,184,146,151,143,194,107, 37, 72, 77, 59, 15,109,121, 0,118,175,223,248,208,250, + 76,103,198,202,109,237, 79, 48, 83, 46,183, 47, 11,183, 56,145, 62,143, 71, 0,106,167, 12, 58, 83, 46, 71, 95, 23, 22, 44, 33, +160,112, 80,203, 99, 99, 99,225,236, 5,152, 59,119, 46, 8, 33,136,141,149,171,108,124,142,153,177,114,244,237,123,183,188,216, +216, 88,187, 59,222, 29,201,177, 37,127,103,140, 31, 63, 30, 35, 70,140,144,122,171, 4, 59,206,213,135,135,135, 75, 83, 83, 83, +213,181,221,103, 19,164,104, 91, 85, 64, 25,229, 43, 50, 50, 82, 42,151,199,170,157,149, 14, 7,249,240, 68, 94,226,252, 38,214, + 83,113,155, 59,158,142,249,249,118,133, 96,207,169,186,199, 62, 87,121, 0,184, 24,128,135, 84, 1, 24, 60,100,208, 61,153,243, +105, 40,203,223,177, 35,121, 3,141,150,160, 93, 27, 30, 8,225,129,240,120,216,187,223, 58,191,239,227, 35,134,143,200, 7,227, +158, 38, 16,251,136,224, 43, 38,208, 20,243,145,113,188, 41,204, 22, 51, 58,118,240,108, 94, 87, 38,147,209,107, 5,151,160,205, +220,133,110, 29,133, 56, 83,232,253,188,240,204,153, 51,213,168,103, 80,158, 76, 38,147,126,249,229,151, 42,198,205, 95, 92, 92, + 60, 49, 60, 60,188, 98,223,190,125, 59,159,123,238,185, 81,197,197,197,100,234,212,169,123,108,249, 2, 26,173,115,166,167,167, +171,195,195,195,165,204,113,125,100,253,184, 97, 35,153,250,202,100,154,125,225, 28,174,229, 93, 1,143, 71, 96, 54, 83,136,125, +131, 16,218,179, 55,118,255,145,204,186, 78,175,221,178, 72, 53,197,215, 84, 85, 85, 38,244,233, 29,130,224,246, 45,145,127,245, + 38,180,167,115,145,149,157,143,253, 7,254,194,149, 66,138, 99,153,103,188,106,167, 7, 37,249,143,101,115,160,215,207,245,255, +132,165,188,220,255, 97,205,154, 53,118, 5, 96,205,154, 53, 64,222,250,187,158,117, 37,143, 45, 40,165,164, 62,253, 56, 54, 54, +182, 94,125,207,129,228,213,222,220,119,229, 85,112,252,174, 43,121, 30,181,243,149, 45, 72, 90,243,178,117,108, 24,254, 72, 13, +242, 7, 0,217,152, 39,172, 7,218,147,110, 21, 0, 46, 15,192,131,131,117, 43, 23,222, 53, 13,224,145, 2,240,128, 7,124,212, +187,112,153, 39,124, 32, 22,137, 48,110, 12, 1,143, 16, 12, 26,104,194,233, 51,190,224, 17,235,156,127, 73, 9, 15,237,219,242, +193, 35, 34,156, 58, 45,130,216, 7, 48, 24, 13,184,146,239,235, 17,249,231,102,255,137,240, 17,207, 64,208, 50, 28,185,217, 25, + 16,220, 72, 66, 64,179, 32, 90, 90,166,105,148, 10, 86, 42,149,106,153, 76, 38, 29, 56,112,160, 42, 46, 46, 14,189,123,247, 46, +210,106,181, 24, 56,112,160, 84,171,213, 98,206,156, 57, 42, 27,249,171, 27,187,145,235, 75,252,206, 74, 0, 0, 68, 14, 29, 36, +105,215,182,157,202,223,223, 31, 63,110,216, 72,206,156,205,245,108, 64, 79,205, 80, 3, 32,102,180,164,231,178,210,209,174, 77, + 19,136,197, 66, 84, 84, 24, 80,120,189, 12, 68,208, 17,199, 50, 83,185,104, 41, 54, 56,241, 6,208,245,255, 80, 99,121,225,241, + 5,141, 90,164,216,216, 32,135,180,181, 13, 67,104,238, 72,217, 19,210,174,111, 62, 3, 87,227,188, 44,210,199,250, 91, 43,175, + 91, 63, 28, 30, 90,244,235,215,207, 30,240,183,110,229,194,187,238,185, 85, 0, 26, 58, 31,255,253,206,239,239,153, 22, 65,160, +213, 18,248,181, 37,104, 17, 68, 48,112,128, 17, 98, 17, 31, 62, 34, 35, 90, 4,137,109,131, 0, 65,196, 64, 51, 50, 78, 8,173, +222, 2,150,138,145, 76, 38,163,189,186, 55,195, 27,115, 63, 66,165,168, 3,126, 77, 46, 68,215,208, 65, 0,128, 38,199,118, 32, + 59, 31,180,162,188,241,148, 0, 0, 36, 47, 47, 79,178,114,229, 74,149,163,119, 0, 0,105, 76,203,255, 94,195,150,236,167,222, +245,126,240,208, 9, 50,245,149,201,244, 86,241, 45, 84,222,208, 67, 44,110,129, 14, 93, 30,103, 53,149,240,176,195,154, 14,187, +129,126,102,222,122,216, 87, 4,228,109,104,244,223,230, 46,184,239,239,134, 81,207, 76,108, 80,203,157,139, 1,120,176,148,128, +218,200,223,173, 7,224,159, 0, 10,107, 84, 63,225, 81, 80, 80, 4, 53,167, 72, 57, 44,128, 88, 36,132,143, 72,128,103,199, 80, + 80,106, 65, 96, 11, 19, 76,102, 2,139,197,108, 27,252,220,227,241,206, 21, 24,251,162, 12, 21,130,110,104,221,196, 31,147, 95, + 8,194,198,173,167,237, 74,128,209,252, 43, 78, 95,104,220,117,226,140, 34,224,112,206,189, 61, 94,120, 21,254,142, 32, 19,180, +132, 38, 6,222,205, 12,202, 32,175,228,173,211,174, 64, 76,224,194,187,111, 28, 95,208,232, 86,255, 63, 25,251,254, 50, 54,100, + 31, 38, 86, 5,145, 58, 40,139,220,180, 64, 99, 41, 1,110, 27,203,219,125,132, 57,112,224,192,129, 3, 7, 14, 15, 47,184, 68, +207, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56,112,224,192, 41, 0, 28, + 56,112,224,192,129, 3,135,191, 7,106,172, 2, 56,121,242,164,215,209,160,174,130, 9, 27, 90,222,148,233,177,110,191,167,211, +220,176, 31,251, 7,181,181, 31,255,252,125,194, 93,207,182,146,190,234, 86,222,190,213,119, 50,230,141,156,255,165,253,248,150, +234, 91,120, 83,190,218,224,109,249,106,131,171,242, 61, 63, 85,238,246,123,153,170,157,232,220,185, 51, 46, 95,190,140,129,210, +177,246,235,191,253,168,184,231,245,231,174,191,196, 7, 7, 75,222, 40, 44,116,204, 76, 72,238,103,255,115,150, 55,118,236, 88, +201,174, 93,187,106,100, 74, 28, 51,102,140,116,231,206,157,234,198,120, 63, 30,100,121,245,145,245,119,174,191,168,168,168,151, +250,244,233,179,241,244,233,211, 47,166,164,164,252,218, 0,229,163, 15,202,251,193,201,107, 92,121, 30, 43, 0,206,248,234,171, +175, 36, 85, 85, 85, 32,124, 33, 8, 33, 48,155,140, 16, 9, 5,152, 51,103,142,186,190,154,199, 87, 95,125, 37, 1,128,217,179, +103,215, 75,150, 78,115, 3,254, 65,109,237,196,223,182, 99,103, 0,192,141,171,151,189,146,183,111,245,235, 24, 57,255, 75, 59, +113,125,181, 45, 3, 0, 48,251,217, 65,127, 75, 13, 48, 83,181, 19, 3,165, 99,145,169,218,105, 37,181,241, 83, 0, 0,151, 47, + 55,126,253,133, 2,146,108, 64, 21, 10, 72,179, 1,213, 27,133,133,200,136,123, 27, 0, 48,104,229,167,141, 90,111, 47,189,244, + 18,221,180,105, 19,170,170,170,106, 92, 23,139,197,170,151, 94,122, 9,191,252,242,203,131,186, 60,112,104,247, 46,193, 27,168, +217,172,207,206,191,177, 8,192, 14,206, 14,170, 29,159,127,254,249,240, 63,255,252,179,217,181,107,215,218, 6, 5, 5, 53, 15, + 11, 11, 43,124,243,205, 55,127,244, 86, 94, 84, 84,212,136,201,147, 39,167,108,220,184,241, 85, 0, 1,147,254, 47,118, 58, 0, +203,233,211,167, 95, 86, 40, 20,191,201,229,114,139,135, 34,153,228,202,180, 1,198, 43,103, 18,105,168, 62, 76,239,129, 76, 14, + 13,237, 1,112,196,127,254, 27, 47, 9,232,216, 71, 21,213,167, 7,252,124,132,160,148,194,108,166, 56,147,115, 5,241,171, 63, +147,250,250, 8, 49,107,214, 44,175,200,251,231, 13,139, 36,189,186, 29, 84,157,201, 14,145,122, 91,112,134,240,125, 3, 90, 64, +167,185, 97, 39,254,186, 60, 2,108, 44,213, 65, 83, 22, 98,223,234,215,237, 47, 82,109,207,213,181,198,210,249,127,138, 68, 34, +235, 91, 64, 41, 44, 22,235,251,109, 54,155,237,229,231,241,133,172,173,104, 0,104,215,218,154,170,211, 80, 86,130,106,147, 9, + 0, 80, 97,178,202,235, 50,106, 6, 30,237,213,159, 21,241, 3, 64,223,193, 35,144,169,218,105, 39,254,218,158,187,159,245,199, + 12, 26,217, 0,158,242,247,199, 30,157, 78,197, 16, 63, 0,100,237,221, 87,215,160, 85, 39, 62,253,105,153,228,248,237, 99, 40, +204, 63,133,110,157, 34,240,191,185,191,120,220,135,199,142, 29,251,220,230,205,155, 25,242, 55, 1,168, 2,224, 7,192, 82, 85, + 85, 37,240,245,245,197,216,177, 99, 37,174, 60, 1,141,140, 54, 79,244,235,243,199,158, 95, 18,154,232, 10,207, 99,168,108,230, +198, 43, 90,227,203, 0,126,123,208, 6, 38,153, 76, 70,189,221,128,199,137, 24,189,194,151, 95,126, 41,201,200,200, 80,109,216, +112, 39, 49,209,237,219,183,145,157,157,141,103,158,121,230, 7,137, 68, 34,125,243,205, 55, 89,181,175, 66,161,224,109,220,184, +241, 67, 0,255,159,189, 47,143,111,162,234,222,127, 38, 73,211,116,223,217,247,150,202, 78,161, 8,200,154, 0,165, 66, 1,101, + 41, 90,208, 87, 68,104, 64, 69, 1, 81,180,175,223,159,190, 46, 8,138, 20,101, 13,139,226,171,101, 43,136, 82, 40, 20, 10, 41, +101,211, 74, 41,101,183,180,165,116,163,116, 79,151,236,153,249,253,145, 76, 76, 67,210, 76,210,176,190,243,124, 62,243,105,231, +206,228,100,114,231,222,251,156,115,238,185,231, 62, 55, 34,242, 69,183,157, 59,119,182,126,249,245, 5, 94, 0,116, 0,218, 26, +110,123, 6, 0,103,244,232,209,163,128,251,183, 58,183, 70,170,131,103,127,136,140,132,149,148,181,254,102, 71,255,160,210,207, +103,128,203,229, 65,167,211, 66, 86,223,128, 89,211, 95,160,234,235,235, 91, 74,216,148, 51,223, 11, 11,219,176,180,237,175,137, +167,192,182, 2,176,102,237, 58,161,112,226, 12,105,199, 86, 62,112, 23,240, 64,146, 36,116, 36,192,227, 18,240,247,233,129,222, +221, 59, 73, 83, 83, 14,139, 54,110,220, 40,180, 87, 9, 88,183,110,157,176,103,240, 89,105,255, 30,183,193,229,232,164,235,214, +175, 23, 45,122,251,109,187,100, 52, 86,151,193,205, 39, 0, 62,222, 94, 0, 96,252,107,233,190, 54, 29,187,216,244, 6, 28,143, +127, 27,131,103,127,136,215, 94,154, 6, 0,198,191,150,238,219,112, 48,195, 46,237,154,203,229,162, 67,135, 14,224,114,185, 80, +171,213,104,108,108,132, 78,167, 67, 77, 77,141, 67, 47,215,147,199,197, 15,107, 15,192,213, 7,184, 87, 0,252,213, 80,130,138, +178, 92,252, 28,255,145, 93, 86,127,255, 97, 99,209,161,157,126,138,164,131, 5,242,239,210,165,139,113, 58, 0, 0,138,139,139, +157, 82,127, 12,147,171, 82,145, 30, 30,248,252,237,183, 0, 0,159,155, 16,255, 47, 57, 57, 77, 7, 19, 59,178,181,206,250,104, +164,176,102,112,170,244,195, 78,175, 64, 69,142,131, 43, 73, 33,226, 5, 29,126,252,102,175,232,248, 6, 48, 29,204,121, 11, 22, + 44,248, 77,161, 80, 96,199,142, 29,202, 57,115,230, 8, 0,120, 2, 32,119,236,216,161,158, 51,103, 14, 79,161, 80, 64, 32, 16, + 72, 91, 58,208, 69, 70, 70, 10,143, 29, 59, 38, 53,108,216,210, 98,120,242, 57,255,111,221,231, 31,184,249, 94,223, 5,183,191, + 79,226,211, 49,126, 94,239, 36, 85,124, 86,175,166, 30, 43, 5,128,222,130,183,166, 38,130,242,247, 79,181,251,183, 15, 25, 50, + 68,248,231,159,127, 58, 76, 54,107,214,172, 17,238,219,183, 79, 90, 95, 95,111,241,250,221,187,119,177,111,223, 62,233,235,175, +191, 46,250,241,199, 31,211,108,180, 23, 98,231,206,157, 63,143,136,124,113,102, 78,214, 57, 94,135,118,109,180, 47,191,190,160, +201,184,123,242,240,175,232,219,183,111,143,157, 59,119, 78,232,219,183,239, 65, 0, 56,115,230, 76,179,253,131, 73,127,211,247, + 15, 2,176,145,136,103,192,128, 1,212,145,148,227,200,186,122,221, 88,166, 84,170,240,245,186, 45, 13, 11,231,196,176,132,253, + 20,227,190, 32,192,213,171, 87, 11, 71,140,159, 42,237,209, 41, 0,174, 46, 28,144, 36,137,178,178, 50, 92,201,206,130, 90, 75, +130, 36, 41, 4,248,184, 99,252,132, 73, 82,133, 74,107,247, 23,186,186,148, 35,184, 83, 25,192, 37,208,171,123, 17, 92,121,247, +236,182,252, 77,201,223, 28,178,186,122,148, 21, 21,192,205, 39,192,170, 87,160, 57,242, 50,199, 79,123,126,197, 91, 83, 6, 99, +240,236, 15,209,140,150,125, 31,248,124, 62,184, 92, 46,188,189,189,145,159,159,143,154,154, 26,189, 34,229, 32,249,183,109,213, + 26,158, 60, 46,166, 46,250, 2, 19,102, 13,195,161,171, 37, 40, 83,160,197,228,111,142,226,210, 50, 92,187,112, 22, 65,126,222, +122,242,231,113,157, 82,127,207, 79,127, 13, 0,224,199,115,177,139,252, 1,224,255,214,111,192,255,173,223, 96, 36,255,148,198, + 70,188, 63,126,146,254, 98, 16,159,209,239, 30, 22,215, 85, 56,255,189,231,164,175,119,126, 19, 46, 28, 79,120,192, 29, 28,112, +209,190,245,112,188,253,249, 82,233,242,164, 30,140,212,136,180,180, 52, 13, 0,252,244,211, 79,114, 0, 2,122, 27,229, 29, 59, +118,144, 0,220, 77,183, 85,142,137,137,113,104, 94, 46, 62, 62, 94,104, 79, 57, 3,140, 24, 52,160,191, 60,241,215, 3,226, 1, +125, 66,185,141,215, 79,160,160,188, 30,119,107,229, 32, 41,202,161, 64, 96,138,162,168,234,234,113,212,168, 81,163,156,154, 72, +204,132,252,225,239,159,234,144,140,140,140, 12, 41, 0,130, 32, 8, 12, 25, 50,196,238, 58, 75, 77, 77,189,143,252, 47, 92,184, +128, 89,179,102, 25,207, 53, 26, 13,110,222,188, 41,141,143,143,111,214,139,185,115,231,206,183, 71, 68,190, 56,233,203,184, 37, +188,196,196, 68,108, 91,183,154,103,240, 24, 25,201, 63, 49, 49, 17,235,215,175, 71,223,190,125, 15,218,234,111,230,228,111,173, +191, 77, 24,110,240, 2,122,121,216,148,247,237,186, 77, 70,242, 47,175,172, 66,121,101, 21,100,245, 13,112,113,225,121,110,218, +177, 75, 9,103,109,136,192,226,161, 34, 44, 44,236,190,163, 89, 5, 96,227,198,141, 84, 64,151,126,232,210,198, 23, 74,141, 14, + 4, 1,164,164, 28,197,127,127,218,129,203,217,217,120,127,233, 98,112,185, 28,144, 58, 18,222,238,174,232,210,111,132,116,237, +218,181,140, 59,216,250,245,235,133,189,187,223,145,122,123,202,241,195, 79,229,224, 16, 20, 6,247,253, 91,186,126,253,122,187, + 58,169, 37,242,167,137, 95, 33,171,106,162, 32,200,234,234,109,202,179,212,153,232,142,148,145,176,178, 9,193,253,180,231, 87, + 70,207, 24, 28, 28,140,128,128, 0,212,213,213,129,207,231,131,195,225, 64,161, 80,160,166,166, 6, 92,174,190,147,219,179,217, +210,254,223, 14, 96,241,218, 99, 56,176,238, 99,180,109,213, 26,238, 30,254, 40,210,149,224,231,248,143,224,105, 24, 52,184, 12, +229, 89, 34,127,154,248,101,165,121,232,209,161, 21,234,229, 74,184,186,187, 2, 58,157,205,120, 0, 91,245,247,209,214, 67,184, +118,241, 60,250,116,235, 5,153,206,182,210, 72,147,255,223,199,142,227,255,214,111, 48,150,167, 52, 54, 34,165,177, 17,249,226, +255,224,216,245,203,232, 61,184, 27, 80,101,123,107,230,209,203,186, 9, 23,190, 51, 86, 26,228,209, 19, 10,170, 30, 80,149,131, +175,170,134, 74, 87, 15, 37,169, 0,201,247, 68,251,145,131, 16,177,176, 51,101,203,154,163,231,253,197, 98,177,187, 88, 44, 6, +244, 83, 0, 16,139,197, 48,156, 27, 44, 40, 37,118,239,222,109,119,167, 93,178,100,137,112,233,210,165,210, 94,189,122, 81, 4, + 65, 72, 1,224,149, 87, 94,161, 58,119,238, 76,125,252,241,199, 14,109,205,236,229,202,217,177,225,195,215,221, 34,219,171,184, +231,110,150,225, 80, 1, 7, 31, 30,185,167,250, 79, 90,131,172, 81,131,215, 28,145, 89, 83, 19,241, 32, 45,127,248,251,167, 98, +246,236,217,118, 79, 17,154, 18, 62, 69, 81, 4,189,157, 52, 83,188,246,218,107,194,123,247,152, 25, 37,106,181, 26, 87,174, 92, + 57,217, 92,123, 1, 32,236,208,174, 13, 63, 58, 58, 26, 0,144,153,153,137,147,135,127, 21, 20,151,150,145, 52,249, 27,126,187, +177,191, 93,185,114, 37,190, 37,253,237,235, 57,147,112, 53,175, 8,109,186,181, 5, 26,229,140,127,123,121,101, 21, 52, 26,173, + 65,193,209, 66,163,209,162,232, 78,129,160,133,175,149,176,113,206,226, 17,162,137, 43, 74,165, 82, 97, 64,143, 30, 82,119, 55, + 23,144, 36, 5, 29, 9,156, 61,125, 6,255,249,252, 11,144, 20,112, 43, 55, 23,151,179, 47,161, 79,159,254,224,114, 9, 60,211, +173, 3,242, 47, 50,247, 2,240,121,229, 8,237, 82, 10,240, 8, 20,221,213, 0, 60, 2,253,122,220, 65,198,149,114,135,127,128, +169,123,223,146,103, 64, 33,171,106,178, 26,192, 22, 76,221,251,150, 52,237,140,132,149,136, 88,178,222, 98, 20,187, 41,180, 90, + 45,220,221,221,193,225,112,224,231,231, 7,185, 92,142,198, 70,253, 54,192, 65, 65, 65,168,170,170,178, 43, 71,182,178, 6, 24, +236,230,134,247,215,157, 70, 68,127,224, 78, 22,240,151,225,218,251,235, 78,227,251, 37, 34,232, 72,157,221,245,119,237,194, 89, +227,255, 99,195,123,128,231,197, 65, 74,218,117, 12,232,209, 17,222,158,174,248,105, 95, 42, 6,137,162, 80,108, 97, 21,128,173, +250, 59,120,157, 2,238, 2, 83,198, 18,216,122, 40, 31, 1,126, 93, 49,109, 56,193,168,254,104,119,127, 74,227, 63, 91, 39, 83, +159,198, 3,237,101, 32,230,127, 2,234, 63,159, 3, 28, 5,136,140, 21,244,160, 98,181, 50,131,167,123, 74, 59,251,134,163, 78, +215, 0, 85, 77, 46,126, 46,220,137, 51, 83,106,208,107,158, 8,227, 23,121,194,205,239, 25, 8,120,126,224, 77,145, 97,158,118, + 30,181,109,235, 54,139,131,148, 88, 44,166,104,165,141,195,225,128,162, 40,181, 65,137, 86,114, 56, 28, 57, 69, 81,254, 0, 72, +180, 96,121,109,124,124,124, 90,100,100,164,168,170,170, 74,154,146,146,162, 87,124, 82, 82,208,179,103, 79,244,232,209, 67, 68, +151,217,131,122, 21,249,206,220,255,251, 62,233,155,168, 54, 28, 74, 41,195,252,132, 28,141, 86,163, 89,175,210, 97, 5, 0,135, + 54,163,120,241, 69,245, 3, 39,255,132,132,132, 52, 71,172,127,211, 41, 19,130, 32, 48,120,240, 96, 33,211, 93, 37,117, 58,157, + 93, 10,195,237,219,183, 33,145, 72,136, 77,155, 54, 89,186, 44, 0,208, 11, 0,111, 76,212,180,218,252,252,124,223,204,204, 76, + 36, 38, 38, 34, 60, 63,159,147,153,153, 9, 0, 8, 15, 15,199,243,163, 7,193,219,211, 21,235,127, 60, 80, 62,107,214,172,184, + 77,155, 54, 45,177,183,191,221,253,109, 37,188,122, 11,224,217,125, 49,246,174,156,135,254,125,218,224,153, 73, 95,216,236, 31, +178,186,122, 8, 4,174, 0, 0, 23, 23, 30,228,114,165,179,121,134, 37,253, 71, 0, 38,155, 1, 53, 25,168, 72,146,132,187, 43, + 31,106, 45, 5,146, 2, 56, 4,240,201,103, 95, 64, 71, 2, 13, 13, 13, 40, 43,187,139,214,173,219,128,162, 72,104,181, 58, 8, + 92,120,224,186, 48,115,193,110,216,176, 65,216,189, 75,177, 52,208,175, 78,223, 28, 12, 7, 65, 80, 24,216,251,150,148, 94, 21, + 96, 15,104,235,158,118,247,155,147, 63, 19,235,223, 92,139,166,137,127,195,193,140,251,200,159,169,245, 15,232, 3,134, 92, 93, + 93,225,227,227, 99,116, 25,210,129,127, 62, 62, 62,104,211,166, 13,180, 90,230,202,211,143,169,167,224,211, 5, 16,134,234,207, +115,180,122,247, 63,160, 47,251,248, 11, 41,106,213,246, 77,201, 20,151,234,131, 21, 59,181,242,135,151,143, 7,120,222, 92, 40, + 43, 21, 0,135,131,182,157, 59,224,108,118,129, 67,245,247,218,123, 95, 98,212,208, 49,224,149, 1, 13,173, 1,119, 14, 7, 67, +187,116,133,120, 74,107, 70,114,204,231,250,127,121,105, 30,166,190, 56, 18, 8, 81, 2,151,121,128, 39, 15,152, 28,142, 14,155, +183, 50,243,198,180,247,135, 90, 93, 13, 66, 85,133,159, 11,119,226,252, 28, 31,140,154, 58, 7, 35, 90, 61, 47,186,122, 76, 11, + 45,217, 8, 23,117, 35,180, 61, 72, 84,220, 99, 22, 52,106, 80,222,148,115,230,204,225, 0,168,161, 12, 59, 68, 25,206, 91,132, +148,148,148,180,158, 61,123,138,220,221,221, 17, 24, 24, 8,119,119,119,164,167,167, 19, 41, 41, 41,105, 14,136,107, 51,105,210, +164,173, 27,182,252,192,249, 36,173,129,220,119, 46, 23, 42,181,166, 81,169,195, 50,123,200,223,220,229,159,158,158, 78,208,199, +227, 66,254,150,220,253,246,122, 1, 26, 26, 26,140,255, 95,184,112,193,120, 0,192,210,165, 75,155,156,155,220,239,106, 69, 92, + 59, 0, 93, 12, 74,161,251,243,211, 95, 81,154,122, 2,104,203,255,185,225,195, 77,251,219, 33,177, 88,172,180,167,191,197, 78, + 30,133,126,225, 61,224,213,223, 11, 37, 39, 10, 1,129, 43,166, 47,250, 23, 6,191,250, 61,163,223,172,213,234, 80,114,247,158, +150,182,252,105, 20,221, 41,104,233,171,165,172, 28, 44, 30, 3,133, 0,150, 44, 21,202, 48,184,145, 20,160, 35,245, 74, 0, 65, + 0,191,238,223,135,169,211,102, 32, 48,168,149,113, 0,164,236,120,151, 92, 78, 57,122,135, 20, 25,207,251,245,113, 55,234,134, + 3,123,229,131,203,177,223, 11, 96,238,238,183,116,221, 30,235,223,220,221,111,233,186,233, 90,246,230, 80, 87, 87,135,250,250, +122,168, 84, 42,144, 36,137,138,138, 10,163,251, 95, 46,151,163,161,161,193,174, 41,128, 3,235, 62, 70,218, 85, 64, 86, 0,104, + 20,192,247,203, 69, 70,247,255,197, 44,224,210,221,179,224,218, 89,127,178,210, 60,248,251,120, 32,192,223, 3,207,132,246, 68, +254,237, 10,228,148, 84,161, 83,128, 15, 84,247,202,145,123, 43,183, 73, 46, 0, 38,245, 55, 76,248, 2, 70,136, 98,112, 32,105, + 47,164,233,123,177,115,205,123,152,254,222, 10, 92,214, 0, 21, 85,229,140,234,207,116,174,255,245, 97, 67, 48,187, 87,103,236, + 61,112, 18,151, 47, 23, 96,205,149, 76,236,142,248, 23,176,253, 28, 74, 74, 42, 24, 89, 23, 29,148,174,208,169, 43,161, 86,235, + 35,171, 91,183,239,136, 30, 61,123,138,234,220,244,177, 24, 10, 82, 14,142,170, 17,110,141, 92,220,187,219,188, 2, 64,191, 51, +165, 82, 9,165, 82, 41, 0,160, 6,224,165, 84, 42,189,205,151, 4,182,192, 11, 32, 76, 79, 79,151,246,236,217, 19,175,188,242, +138,168,178,178, 18,211,166, 77,179,103,224, 28,193,231,243, 27, 60, 61, 61,181, 17, 17, 17,119,151, 47, 95,222, 46, 46, 46, 46, +255,175,172,203, 19,119, 95, 83,221,212,144,176,123, 63,214, 7,225,242,119, 38,249,155, 91,255,180,194, 66,191, 51,166,177, 0, + 46, 46,255,196,168,172, 89,179,198,120, 88, 58, 7,140, 43,124,172,189, 27,190,225,224, 0,224,201, 74,243, 44,186,211,233,254, +150,117, 49,235,246,172, 89,179, 98,237,233,111, 35,159,125, 6,227,134,135,226,203,207, 86,227,219,181,201,248,127,191,156,196, +130, 49,131, 80,246,123, 50,100, 53,117, 76,250, 7, 17, 61,229,121,104, 52,218, 44,141, 70,171, 53, 85, 0, 0, 96,197, 39, 31, +181,196,130,103, 45,255, 71, 8, 75,115,255,230, 74, 64, 19, 5,128,195,225, 64,214, 32, 7,151, 67, 64,171,213,129,164, 40,104, + 73,125, 16,105,246,165, 44,140, 25, 27,169,119,147, 81, 20,184, 28, 46,234,229,106,104,213, 42,219,214,255,198,141,194,174,237, +239, 74,131,252,101, 70, 45, 99,216, 96, 79, 67,140, 46, 1,130,160, 48,160,103,174,116,195,198,141,140,189, 0,180,117,223, 92, + 48,160, 67,214,107, 51,193, 53,246,192,207,207, 15, 21, 21, 21,112,117,117, 69,125,125, 61,130,130,130,140, 65,129, 74,165, 18, +181,181,181,118, 41, 0,177, 95,238,198,247,203, 69,240,233, 2,164, 93, 5,222, 89, 37,133, 39,143,139,105,239,126,133, 98,178, + 12, 9,107, 62, 0,151,195, 92, 30,109,253,135,135,135, 34,168, 91, 23,180, 10, 10, 4,159, 67, 64, 75, 80,168,104, 84,160,166, + 94,233, 80,253,125,187,242, 55,188,216,179, 43,188,189, 3,224, 30,212, 14,154,234, 26,100, 29,218,133,218,234, 66,135, 26,241, + 15, 43,223, 6,150,140, 3, 79,171, 70,151, 70,160,156, 91,135,239,239,254, 5,240,189, 25,203,184,152,244,135,168,146,163, 64, + 33, 95,142, 65, 33, 34,244,250,151, 39,242,253,210,164, 65, 65, 89,210,142, 67,243, 33,227,212, 67, 69, 41, 32,255,133,132,192, +211,139,137,229,111, 58,192,211,171, 0,248,206,234,184, 71,143, 30, 5, 0,204,158, 61, 91, 20, 31, 31,159, 54,117,234, 84,163, +197,200,132,252,131,130,130,142,108,221,186,213, 67, 34,145,112,151, 44, 89,130,197,139, 23, 83,231,206,157, 27, 10, 32, 69,161, + 69, 79, 0,127,218,251, 76, 98,177,159, 85,183,191,163, 1,129,206, 36,127,115,130, 55, 85, 88, 40,138, 34, 12,129,129,182,251, + 69,113,241, 57,250,255,157, 59,119, 26, 15,243, 50, 26,254,254,254, 16,139,197,214, 6,193, 98, 0,181, 0, 56,197,165,101, 56, +127,254,188,113,206, 63, 60, 60, 28,128,126,251,237, 61, 7,147, 81, 83,175,148, 3, 88, 33, 22,139,117,246,244,183,223, 15,124, +138,200,229,139, 48,113,226, 88, 4,186,114, 81, 79, 80, 72,201, 41,194,249,171, 37,118, 17,245,194, 57, 49,207,230,231,230,242, +138,238, 20,128, 62, 12,228, 15,214,106,127, 50,137,223,188,204, 18,154,196, 0,184,186,186,226,214,245,203,162, 46,237,252,165, +110, 46, 60,232,116, 36, 8,130, 0, 65, 0,177,226,183, 64, 81, 36,116,134,124, 0,114,165, 18, 55,114,242,193,231,219,140,234, +134, 86, 83,141, 1,189,110,155,142, 24,120,115,201,109,236,255,165,187,177,105, 13,234,147,135, 63,178,123,218,109,253, 91, 34, +126,133,172, 10, 0, 28,178,254, 45,117,180,140,132,149, 0,192,216,250, 7,244,235,252,219,180,105, 3,149, 74,133,123,247,238, + 65,167,211, 33, 48, 48, 16, 85, 85, 85, 8, 12, 12, 52,212, 43,115,194,174, 40,203,197,199, 95, 72, 33, 43, 0,190,121,111, 36, + 26,180, 58, 44, 93,149,136,239,150, 71,227,189, 53,135,192, 35, 8,216,193,255,144,149,230,161,109,160, 47, 92,224, 2, 29, 8, +220,189,125, 13,119,202,101, 8, 14,242,199,239, 23,207,225,198,117,216,109,253, 79,159,187, 20, 46,254, 0,135, 11,236, 72,190, +141,253, 27,223,199,220,149, 18, 44,157,220, 31,111,141,237,108, 87,253,165, 52, 54,226,219, 41, 51,129, 90, 1, 64,184, 0,223, +174,198,140,191, 78,227,216,216,133, 32,190, 90, 4,226,143, 15, 24, 91, 24,151,238, 6, 96,136, 66,134, 6, 55, 46,228, 2, 1, +130,167,187, 64, 69, 41, 32,227,184, 64,139, 80, 80, 58, 57, 52,149,119,113,118,157, 12,179,103, 5, 35, 77, 42,125,232,157, 54, + 54, 54,150, 2,128, 45, 91,182,208,174,126, 98,201, 18,253, 52,240, 47,191,252,194,244,205, 14,111,215,174,221,209,175,190,250, +202,227,214,173, 91,112,113,113,129,183,183, 55, 46, 95,190,172, 1, 80,209,146,231,107,110, 77,190, 35,222, 1,103,146,191,185, +245,175, 39,230,251,151, 15, 26,150, 7,166,217,120,174, 91,123,246,236, 25,198,116,122, 78, 32, 16,204,181,174, 52,137,235, 71, +143, 30,125, 27, 64,120, 78,214, 57,152,206,249,191, 57,119, 38,142,118,235,134,196,196, 68,100,102,102,226, 72,183,110,238,179, +102,205,250,241,212,169, 83,140,251,219, 75,227,134,192,135,244,131, 28, 46,216, 31,191, 8, 27, 15, 93,194,251,207,143,192,156, + 53, 59, 49, 99,197,207,246, 90,224,196,138, 79, 62,178,148, 8,136, 50, 81, 2, 88,139,254, 41, 67, 19, 15,192,155,111,190, 73, +212,222,205, 69, 94, 81, 21,120, 46, 92,104,117, 36, 52, 90, 29, 46, 94,204,196,127,255,251, 35,212, 58, 10, 26, 29, 74,253,203, +119, 0, 0, 32, 0, 73, 68, 65, 84, 9, 62,143,131,242,154, 6,148,220, 56, 47, 90,188,120,113,179, 29,106,227,198,141,194,158, +193,119,254,177,254, 13,237,106,255, 47,161,250,246,196,161, 0, 14, 5, 14,135,196,208,254, 55,164, 27, 25,120, 1, 44, 89,255, +166,171, 0, 60,252,219,216, 69,254,150,172,127,211,168,218,136, 37,235,237, 34, 47,253,160, 88,131,134,134, 6,184,184,184, 24, +173,127,146, 36,141,127,237, 85, 0,126,142,255, 8, 23, 75, 78,193,179,141, 62,232,207,139,199, 69, 69, 89, 46,188, 93, 93, 80, + 91, 93, 12, 46,135, 0,143,195,108,250,153,182,254, 59,250,123,225,122,254,109,104,213,106,184,242,248,104,104, 80,226,119,233, + 57, 12, 18, 69,217, 69,254,116,253,189,240,246,231, 72,248,254, 59,200, 73,160, 99,112, 7, 92,189,246, 7,150, 78,238,239, 80, +253, 1,192,210,224, 65, 72,186,117, 18,144,105, 1, 65, 32,142,103, 92, 7,241,213, 34,122, 96, 98, 92,121,167, 86,231,167,157, + 61,158, 1,168,235,209, 64,212,163,134,211, 0, 25, 79, 3,141,174, 14,174, 74, 57, 4,165,183,177, 59,238, 22,186,132,133,194, + 90, 0,160, 57,220,220,220, 76, 73, 0, 2,129,192,226, 53,166,216,186,117, 43,182,110,221,218,162,206,236,229,229,245, 78,110, +110,174,135,183,183, 55,220,220,220,224,239,239,143,138,138, 10, 16, 4, 33,119,230,160, 65, 91,252,209,209,209, 20,160, 15, 8, +180, 39, 40,208,217,228, 63,100,200, 16,161,173,128, 90,166,177, 0, 30, 30, 30,177, 60, 30, 47,207,188,124,205,154, 53, 77, 44, +127, 0,232,220,185, 51,198,141, 27,183,195,150,253, 83, 92, 90,214, 36,218,255,227,255, 91, 2, 87, 30, 31,173, 91,183, 6, 29, + 19, 96,184,238, 97, 79,127,155, 39,236,135,197,171,191, 67,253,189,114, 4,121,183,194,181,235,133,152,179,102,167,221,253,195, +140,240, 9,179,207,155,202, 97, 61, 1, 79, 0, 46, 93,186,212,108, 50, 32,171, 30, 0, 0, 88,182,108, 89,218, 55,171, 9, 17, + 69, 77,145,118,105, 23, 0, 47,119, 87,244,234, 19,134, 94,189,251,131,199, 1, 26, 20, 58, 20,222,173, 70, 70,218, 97,145,167, +135,187,205, 47,104,148,203, 17,218,249, 46,148, 42,129, 33,107,139,190, 25,185, 9,148,160, 40,160,186,214, 21, 32, 0, 47, 15, + 45,250,134, 22,224,244, 5,219, 89,236, 76,173,127, 83,139,223,205, 39, 0, 46,148, 6,208,254, 51,222,233,120,182,159,209,212, +250, 55,181,248,233,178,220,107, 89,198,123,153,100,217, 51, 85, 2, 0,160, 77, 27,189, 50, 82, 93, 93, 13,111,111,111,163,251, +223, 30, 5,128, 86, 2,128,175,176, 48,122, 52,240,253,105,108,252,119, 20,102,188,247, 29,118,174,124, 11, 60,130, 0,223,149, +217,138, 29,218,250,191, 94, 88,142,144,142,129,216,190,109, 55,186,116,233, 2,159,118,193,232,223, 46, 24, 26,213, 63,238,127, + 23, 6, 50,105,235,255,139,185, 99,241,206, 39, 59,208,177, 27,209,162,250,163,173,255,241, 7,126,192,177,217, 49, 32, 58, 12, + 5,160,207, 10, 8, 0,183, 27, 27,141, 74, 98, 14,152, 37,240,217, 48, 39,143, 24,189,140, 18, 6, 79,171,151,118,233,222, 7, +117,110,192,109,220, 65,125, 65, 5, 42, 86,232,208, 80,211, 1, 55,207,230, 48,126, 33, 36, 73, 18,110,110,110,148, 66,161,128, +137,229, 73,185,185,185,129, 36, 73,226, 81, 12,150,245,245,245,223,188,245,214, 91, 83,182,110,221, 42,240,241,241,129, 84, 42, +197,218,181,107,235,212,106,245,243,206,252, 30,218,226,167,151,203,217, 27, 8,152,152,152, 72, 24,146,252,180,152,252, 1,192, +132,216,109,214,185,173, 12,131, 98,177, 88, 45,145, 72,134,238,221,187,247,114, 99, 99, 99, 91,141, 70,191,204,212,156,252,123, +245,234,133,161, 67,135, 78, 18,139,197,182,190,147, 39, 43,205,195,151,159,126,140, 95,147,142, 32,114,196, 64,156, 72,253, 67, +111,192,180, 11,134, 79,187, 96,132,231,231,227,249,233,175, 84, 22, 86,201,199, 3,216,199,212,250, 95,188, 37, 9,113,111,140, + 71,187, 54, 66,163,114, 97, 94, 15, 45,204,166,200,122, 2,158, 34,165,128,145, 2, 0, 0,239, 47,123, 47,237,155,111, 72,209, +237, 14,207,160, 91,247,158, 82,111, 15, 55,144, 20,160, 80,169,145,159,159,143,138,252, 75, 34, 47, 79, 15, 44, 92,184,208,102, +199,117, 19, 8,176,247,232,104, 17, 29, 1,223,172, 59,130,195,129,135, 7,115,235,137, 94, 2,232,225,223, 6,164, 78,163, 39, +127, 3, 52,132,139,205, 20,187,230,160,151,212, 68, 44, 89,223,132,180, 28, 33,127, 83, 37,192, 52,241, 79,117,117,181,237, 23, + 96, 67, 9,248,217,100,149,240,214, 21,111,254,115,162,105,128, 39, 67, 57, 29,253,189,176,247,194, 37, 92,189,249, 55, 6,137, +162,154,144,190, 61,228, 79,227,133,183, 63,199,254,129, 30,120,123,106, 15,167,212,223,210,224, 65,120,239,224, 94, 16, 95,126, +130, 35,173,135, 96,109,195,213, 38,215,167,249,248, 98,165,172,214, 46,226, 56,181, 58, 63,205,143, 23,129,226,154, 60, 84, 84, +221,197,189, 28, 79,112,117,222, 24,222,111, 36,118,159,221,253, 72, 7, 53, 39,101,251,187,240,227,143, 63, 70, 16, 4,113,252, +187,239,190, 19,188,248,226,139,117,114,185,124, 60, 28,152,243,111, 14,206, 88, 2, 40, 22,251, 57,133,252, 45, 88,169,182,148, + 15, 6,207, 38,174,148, 72, 36,193,245,245,245, 95,102,102,102, 46, 41, 41, 41, 65, 99, 99, 35,248,124, 62,218,182,109,139,160, +160,160, 23, 37, 18,201,239, 63,255,204,104, 75,128, 27, 0,194, 59,250,123,225,185,231,158,195,165, 91, 37, 8,236,218,187, 73, +127,123,126,250, 43,114, 0,235,190,140, 91,178,143,233,239,152, 39,236,135,136,212, 63, 49,251,147,255, 98,212,168, 81,104,221, +186,181, 69, 69,203,137,175,157,112,128,252,169,102,202, 89, 37,226, 17,144, 62,163, 84,192, 0,240,254,251,239,167,109,216,176, + 65,120, 49, 45, 71, 4,232, 35,105, 41,138,130,171,171, 43, 62,120,127, 25,227, 78,251,182,157,105,126,153,130,118,245,115,181, +114, 64, 43, 55, 70,192,211,196,111,239, 90, 44,218,213,159,123, 45, 11,185,215,178, 16, 20, 20,132,138,138, 10,135,136,223, 39, +168, 29,212, 12,130, 35,153, 98,246,231, 63,227,220,105,231, 85, 99, 65, 65,129,113,183, 63,141, 74,121, 31,249,219, 67,252, 52, +254, 53,208,195,105,245, 7, 0, 68,252, 7, 70,226,167,201,255,118, 99,163,104,154,143, 47, 82,128,180,149,178, 90,135,126,251, +111, 43,143,155, 12, 60, 10, 0,192,238,107,204, 19,246, 80, 20, 69,184,186,186, 26,189, 0,244,255, 0,224,234,234, 74, 88,250, +255, 33,227,204, 15, 63,252, 48,106,223,190,125, 75,235,234,234,226, 1,100, 56,251, 11,156,177,244,207,201,228,228,116,136,197, + 98, 5,128,165,134,163, 69,239,227,202,149, 43,195, 1,116, 13,236,218, 91,174, 81, 41,221, 13,253,173, 14,128, 12,192,141, 78, + 1,238, 47,137,197, 98,187, 26,116,196,199, 91, 31, 22,241, 59,164,104, 57,120, 63, 11, 39, 32, 44, 44,140, 17,249,219, 52, 64, + 91,186, 83,223,131, 0, 61,183, 79, 19, 63, 90, 72,252,244,220,180,172,188, 24,178,242, 98, 4, 5, 5,181,200,226, 7, 0,173, +142,180,219,251,208, 28,202,171,101, 14, 63,139, 57,232,185,125,103, 17,255, 3,168, 63, 2, 0, 34, 61, 60, 40, 83,171,127, 0, +207,165, 69,196,255, 63,134,191,234,234,234, 98,216,106,120,244, 56,117,234,148, 68, 34,145,252,183,176, 74, 46,215,168,148,166, +243,145,222,157, 2,220,253, 28,216,253,143, 0,244, 83, 25, 79,154, 82,197,226,225, 42, 1,140, 26,147,163,251, 8,179, 96,193, +130, 5, 11, 22, 44,158, 92,112,216, 42, 96,193,130, 5, 11, 22, 44, 88, 5,128, 5, 11, 22, 44, 88,176, 96,193, 42, 0, 44, 88, +176, 96,193,130, 5, 11, 86, 1, 96,193,130, 5, 11, 22, 44, 88, 60, 21,104,178, 10,224,210,165, 75, 14, 71,145, 90, 10, 38,100, +229,177,242,156, 37,207,176,183, 58, 7, 0,105, 41,249, 10, 91,127,214,229,133,133,133,209,117, 71,175,229,166, 46, 93,186, 68, +178,245,199,202, 99,229, 61,189,242,236, 86, 0,158, 18,180, 40,201, 68,116,116,180, 16,128,105,202, 80, 81, 98, 98, 98, 26,171, + 43, 62, 26,124,253,245,215,175, 94,185,114,165,255,249,243,231,223,115,117,117,133, 92, 46,255, 64, 34,145,172,102,144,129,141, +197, 63, 3, 11, 5, 64,199,214,196,227,141,168,168, 40,225,225,195,135,211, 28,252,172, 40, 57, 57,249,164,147, 18, 74, 33, 42, + 42,234,165,228,228,228,221,155, 55,111,246, 7, 80, 15, 64,199,246,185,167, 15, 79,213, 20,128,129,188, 91,244,249,189,123,247, +154,231, 11,151,182, 68,110,116,116,180,208,176,102,151,138,142,142,166,236,149, 69,217, 9, 75,235,131, 91, 40, 79,248, 40,222, +165, 68, 34, 33, 22, 45, 90,180,250,218,181,107,223,119,238,220,249, 61,129, 64, 0,149, 74, 5, 0, 95,239,223,191,159,156, 58, +117,170,232, 17,117, 25,202,254,227, 97,202,179,186, 7,187,233, 94,236, 14,237,207, 30, 29, 29, 45,164, 40,138,162,254,159,101, +217,244, 53, 91,109,208, 18, 10, 10, 10,168,130,130, 2,167, 17, 76,117,245,184, 38,251, 21, 56,155,168, 9,130,176, 75, 46, 73, + 82,148, 78, 71, 81, 36,105,249,136,138,138, 18, 38, 39, 39, 59,180, 11,213,150, 45, 91,198, 28, 57,114,228,228,232,209,163, 65, + 16, 4,181,107,215,174,113,246, 62,155,249,113,228,200,145,221, 47, 15,227, 67,188, 64, 92,157,231,153,191,111,254,252, 88,146, +190,102, 75, 94, 99, 99, 35,213,216,216,216,108, 59,164,239,121, 16,239,135,133, 85, 67,224,190, 4, 65, 60, 27, 29,222, 98,222, +108, 91,249,180, 31, 33, 90,180,141,219,222,189,123,165, 51,103,206, 4,160, 79,170, 97,210, 56,165,142,120, 21,104,133,130,206, +249,111, 72, 67, 42,141,142,142,182,207,171,144,232,111,199,183,218,238,251,141,147,223,100, 46,206,254,125,109,172,117,104,198, +245, 39,145, 72, 8,153, 76,182,167, 79,159, 62,211, 1,112, 40,138,130,155,155, 27,202,203,203, 81, 91, 91, 11, 31, 31, 31,148, +151,151,159,156, 58,117,170,232,192,129, 3,105,118,190, 19,138, 78, 7, 75, 16, 4,166, 79,159,142,113,227,198,137, 22, 44, 88, +192, 88,206,193,131,191, 25,255,159, 50,229, 69,155,231,182,160, 56,247,246, 63,213, 61,108,125,147,115,243, 50,183, 97,182, 55, + 85,162,183, 19, 54, 69,122,122, 58, 86,172, 88,113,223,187, 24, 57,114, 36,117,250,244,105, 70,109, 57, 49, 49, 81,138, 79, 8, +250,252,254,196, 51,159, 16, 45, 30,204, 31,227,177,165,137,165, 45,145, 72, 68,177,177,177, 24, 53,106, 20,117,230,204, 25, 70, +159, 61,103, 37, 39,227,129,196,247,144,156,156, 44,165, 55, 9, 27, 53,106, 20, 85, 87, 87,215, 28,225, 11, 99, 99, 99,141,237, +245,247,223,127,119, 39, 8, 2, 49, 49, 49,247, 0,180,158, 53,107,214,113,137, 68,194,177,199, 98, 95,125,124,181,241,255,178, +148,187, 32, 8, 2, 59,223,117, 7, 64,224,155, 87,190,126, 33, 48, 48, 16, 0,176,235,167,157,140,235, 42, 60, 60, 28,221,186, +117, 99,153,247, 49, 33,127,123, 61, 0, 84, 98, 98, 34,194,195,195, 41, 43, 3, 40,229, 64,231,118,170, 53,105, 46, 47, 49, 49, +209,116, 67, 12,187, 65, 16, 4,145,152,152, 72,208, 3,144,225,175,195,150, 38, 77,254,134,103, 34, 76,158,205,110, 69,133,152, + 89, 99, 60,152,148,219,130,231,161, 77,198,131, 73,185, 61,228, 79, 81, 20,232,221,217, 40,202,190,102, 34,145, 72, 56, 53, 53, + 53,255,245,241,241,153, 14,128, 51,119,238, 92,204,158, 61, 27,124, 62, 31,110,110,110, 16, 8, 4, 32, 8, 2, 92, 46, 23, 50, +153,140,113, 61, 70, 68, 68, 8, 1, 80,251,246,237, 3,253, 78, 40,138,194,254,253,251,177, 96,193, 2,169,225,250, 99, 7, 75, + 10,193,163,240,172, 37, 38, 38, 74, 1, 16, 47,221,156,137,153, 55, 44,246, 49,106,230,141,104, 17,241,153, 67,253,142,122,255, +253,247,209,181,107, 87,167, 60, 47, 65, 16,148, 88,236,135,128,128, 19, 78,173,135, 9, 19, 38,140, 77, 77, 77, 61, 73, 81, 20, + 17, 27, 27,155,102, 15,249, 91,195,129,196,247, 16, 31, 31, 15,146, 36,241,222,123,239, 49, 82, 40, 76,201, 31, 0,142, 28, 57, +146, 52,106,212, 40, 0,240,139,137,137,209,142, 30, 61, 26, 98,177,152, 52,196,205, 48,241, 50, 54, 57, 95,187,118, 45, 94,122, + 78,111, 27,238,124,215, 13, 47, 15,227,227,131,200,247, 25,255, 38, 15, 15, 15,140, 26, 53, 10,153,153,153,198,241,212,252,160, +239, 97,179, 23, 62, 58,242,111, 86, 1,160,201, 42, 51, 51,211,152,118,210,212,122,178,151,104, 77, 6, 17,103, 15, 74,230,202, +128, 83, 93,195, 22,166, 4,236,134,169, 66, 97,176,254,159,198,118, 70,153, 14, 38, 37, 37, 37,198, 11,197,197,197,140, 21, 70, +153, 76,246,149, 92, 46,127,133,195,225,112,102,205,154, 5,153, 76,134,210,210, 82,184,184,184,128,199,227,129,199,227,193,197, +197, 5,110,110,110, 80, 40, 20, 96,226, 66,220,188,121,179,240,248,241,227, 82,130, 32, 48, 99,198, 12, 80, 20, 69, 43,121,196, +140, 25, 51, 0, 0,169,169,169, 82,118,168,104,158,252, 13,239, 87,100,170, 36,211,239,222,212,171,229,200,160,158,152,152, 72, + 24,222, 11, 54,111,222,236, 20,101,236,163,143, 62,162,141,130, 22,123, 38, 34, 35, 35, 35, 46, 92,184,144,218,165, 75, 23,132, +132,132, 80,195,135, 15, 55,122, 78, 12,187, 63, 58, 68,254,107,214,172, 1, 65, 16,224,112, 56,184,112,225, 2,152,120, 99,204, + 60, 18, 47, 16, 4,129,151, 95,126, 89,107, 40, 82,199,196,196,212, 9,133, 66, 44, 88,176,128,156, 56,113,162,205,223,110,186, + 43,105, 89,202, 93,128, 0, 18,222,249, 39,107,241,206,119,221, 17, 51,220, 21,203,159,255,128,241,115, 49,177,252, 89,239,192, +195, 35,255,216,229, 43, 45, 94,231, 53,215, 33,195,195,195,169,204,204, 76,208,158, 0,154,184,194,195,195,237,234,228, 15,154, +252, 77,173,234,199, 61, 96,207,116, 74,224,169,211, 0, 40, 10, 37, 37, 37, 40, 43, 43, 51,150,153,159,219,176,254,185, 71,143, + 30,157, 24, 26, 26, 10, 46,151,139,220,220, 92, 80, 20,133,191,255,254, 27,106,181, 26, 4, 65,128,199,227,129, 32, 8,232,116, + 58,200,229,114, 28, 56,112,192,166,220, 19, 39, 78, 72, 1, 96,198,140, 25,247,181, 91,122,170,135, 38, 10, 38,237,218,220,173, +111,235,156,137,149, 79,195,218,116, 0, 19,215,191, 57,210,211,211, 97,176, 12, 91,166, 0,127, 66,128,248, 76,175,192,153, 42, +175, 20, 69, 1,159, 16,152,121, 35,218,225, 64, 89,130, 32, 40,195,123, 49,146,145,225,125, 17, 45,145,215,189,123,247,251,200, +205, 81,184,186,186, 82,215,174, 93, 67, 69, 69, 5, 81, 81, 81,129,176,176, 48,170,160,160, 0, 92, 46, 23, 90,173,214,161, 47, + 24, 61,156, 75, 43, 15, 88,182,108, 25,214,174, 93,139,211,167, 79,131, 32, 8, 76,158, 50, 31,119, 10,152,109,224,120,228,200, +145,223, 12,239, 88, 9,128, 52, 28,136,137,137,169, 5,224,155,156,156,140,168,168, 40,161,169, 66,222, 28,244,214,255,253,251, +152,232,167, 3,128, 93, 59,179,236,146,199,226,241, 37,255,102, 61, 0, 6,235,159, 48,245, 4,208,150,127,102,102,102, 75,200, +223, 86,128,146, 67,242, 76, 60, 19, 66, 56, 16,224,244, 0, 44, 39,202,100,240, 49, 62, 15, 93,230,172,224, 23,106,175,159,241, +112, 6, 26, 38, 45, 52, 30,118, 88,254, 20, 61,216,118,232,208, 1,131, 6, 13,194,160, 65,131, 0,192,120,110,126,175, 21,248, +250,251,251,247, 81,169, 84,168,174,174,198,185,115,231,144,145,145,129,138,138, 10, 40, 20, 10,208,115,164, 20, 69, 65,163,209, + 64,165, 82, 49,154, 98,160,219,134, 53,114, 79, 76, 76, 36, 8,130, 0, 83,207,204,193,131,191, 25, 15, 38,231,182,160, 56,247, +118, 19,162,167, 15,211,115,211,123,152, 98,212,168, 81, 72, 79, 79,111, 89,131, 48,153,243,135,126, 26, 75,100, 32,103,130,190, +134, 22,198,222,152,190, 23,218, 11,224, 44, 56,195, 11,208,190,125,123, 20, 23, 23, 19,230,202,174,163,228,127, 32,241, 61, 99, + 27,166, 49, 98,196, 8, 0,192,169,179,204, 23,107, 68, 69, 69, 69, 26,230,254,175, 3,144, 27,198,115,250, 48,106,221, 76,131, + 11,155,206,253, 91, 80,174,236,148,199,226,241, 7,143, 73,231,164, 61, 1,246, 90,254,203,151, 47,167, 86,173, 90,229,180,135, +181, 37,207, 48, 72, 57,173,113, 50,157, 67,107,142,116, 76,100, 53,136,197, 98, 79,107,215, 29,133,233,220,191, 51,148, 0,211, +185,127,166, 74,192,236,217,179,225,225,225, 1, 79, 79, 79,120,121,121,193,199,199,135,244,243,243,227, 36, 39, 39,227,213, 87, + 95, 53,222, 39, 16, 8, 48,126,252,120, 52,163, 4, 4,168,213,106, 84, 87, 87, 67,169, 84,194,199,199, 7,174,174,174,208,106, +181,160, 40, 10, 58,157, 14,106,181, 26, 26,141, 6, 58,157,206,174,248, 2, 67,208,154,213,235,166, 86,232,163,132,173,128, 64, +123,209, 82, 37,128,248,204,250,116,223,204, 27,209, 6,114,117, 80,182,153,245,111, 82,142, 25, 51,102,216, 29, 12,104,110,253, +155,202,115, 20,225,225,225,148, 78,167, 67, 88, 88, 24,117,233,210, 37, 34, 44, 44,140,210,104, 52,144,201,100, 14,203,164,141, + 41, 30,143,135, 37, 75,150,224,194,133, 11,248,103,222,159,121,155, 62,122,244,232,209,145, 35, 71, 2,128,151,129,244,229, 0, +176,123,247,238, 86,167, 78,157,242, 54,244, 15,194,240,215,166,224,181,223,173,197,203, 67,239,183,254,103,127, 47,199,238,115, + 26, 80, 20,133, 1,179, 6, 32,107,103, 22,241, 40,141, 43, 22,206,177,254,109,122, 0,104, 75,149,110,176,166,241, 0, 76,176, +106,213, 42,218, 98,112, 10, 24,200,115,120,126,221,176, 68,175,201,145,154,154, 74,210,171, 2, 90,106,177,199,198,198,122, 62, +205, 13,110,203,150, 45, 88,179,102, 77,147,118, 69,147,255,148, 41, 83, 48,101,202, 20,189,133,115,234, 84,115, 98,252,243,243, +243,149, 58,157, 14, 53, 53, 53,168,172,172, 68, 77, 77, 13,228,114, 57,228,114, 57, 26, 26, 26, 80, 87, 87, 7,153, 76, 6,133, + 66, 1,149, 74, 5,157,206,182,197, 68, 16, 4,246,237,219,103,151,194,246, 36, 35, 61, 61,189,201, 97,138, 37, 75,150, 8, 77, +207,153,204, 57, 91,152,243,111, 98,185,183, 36,144,203,210,103, 41,138, 34,246,237,219,231,212, 88,128,125,251,246,217,221,135, + 7, 14, 28, 72,233,116, 58, 99,130,150,176,176, 48,138, 36, 73,220,187,119, 15,141,141,141, 14,253,230,127, 47, 31,141, 83,167, + 78,129,220,227, 11,138,162, 16, 31, 31,111,124, 71,233,231, 72, 48,157,249,136,138,138,122, 17, 0, 98, 98, 98, 74, 12, 10,128, +106,215,174,132, 86, 11, 23, 46,108,117,234,212, 41, 76,152, 48, 33,194,158,156, 0,101, 41,119, 65,128, 64,130,137,245, 63,235, + 59, 57,184, 47,203,176,235,156, 26,139, 23, 47,198,170,163, 95,179,204,250, 20,145,191, 77, 15,128,249,188,191,105, 60, 0,211, +105,128,196,196,196, 52, 67,128,144,212,204,147,228,232,128,113,159, 60,122, 90,192, 48, 15,233,148, 9,246,113,227,198, 93, 77, + 77, 77,237,243, 56,190, 96,218,234,119,150,219,159,182,250,237,112,251, 55, 65, 66, 66,130,241,255,255,252,231, 63,248,241,199, + 31, 1, 64, 13,128, 79, 19, 63, 0,140, 31, 63,222,150, 2,160, 8, 13, 13,133, 92, 46,135, 90,173, 70, 69, 69, 5, 92, 93, 93, +193,227,241,140, 30,128,198,198, 70,200,229,114,168, 84, 42,200,100, 50, 76,159, 62, 93,180,127,255,254,102,159,143,182, 50,109, + 44,107,197,140, 25, 51,108, 42, 10,122,133,230,193,197, 0, 56,114,221, 28, 38,203,253,238, 67,124,124,188,116,201,146, 37,162, +248,248,248,180, 71,218,134,173, 88,255,166,176, 39, 22,192,154,245,239, 40, 6, 14, 28, 72, 93,188,120,145, 8, 11, 11,251,148, +110,218, 58,157,238, 19, 15, 15, 15, 84, 86, 86, 58, 52,198,124,252,225,104,164,165,165,129,216, 23, 0, 0, 56,246,177, 23,198, +127, 81,143, 81,163, 70,225,203, 85,167, 64, 81, 20, 99,111,197,145, 35, 71, 14,140, 30, 61, 26, 0, 42,118,239,222,217,254,212, +169,211,190, 20, 65, 97,226,132,137, 83, 14, 31, 62,156,116,248,240, 97, 70,114,104, 47,231,218,181,107,241,242, 48,151,166, 22, + 63, 40, 44, 89,188, 4,173,199,183,193,211, 26,183,244, 84, 27,101,171, 62,180,170, 32,132,133,133, 53,175, 0,152, 70,252, 27, +200,223, 24, 44, 69,123, 2,152,106,254, 22, 72,187, 69,176, 32,207,233,115, 82,177,177,177,125, 82, 83, 83,157, 57,224, 61,173, +237,140,128, 62, 10,220,104, 73,191,254,250,235, 0,192, 55,105, 75,198,107,134, 65,203, 26,174, 13, 29, 58,244,213,180,180,180, + 68,157, 78,135,186,186, 58,104, 52, 26,227,188,191, 82,169, 52, 46, 49,164, 3, 3,247,239,223,159,198,160,189, 16, 48, 44, 1, + 52,111,183,209,209,209, 20, 77,250,227,198,141, 19, 49, 81, 0, 30, 84, 30, 0,211,185,127, 83,242, 55,159, 22, 96,240, 62,154, + 3, 21, 31, 31, 47,125,233,165,151,176,103,207, 30, 71,189,101, 66, 83,207, 9,125, 78, 7, 12,206,188, 17, 77,221,186,117,203, +234,231,233,132, 63, 71,143, 30,181,234,177,187,125,251, 54, 99,207, 76,117,245, 56, 10, 0, 34, 34,242,145,159,159,111, 49,186, +188,170,106, 44,128, 26, 0,182,199,173, 94,189,122, 81, 23, 47, 94, 36, 12,131,229,167, 0,192,225,112, 62,185,115,231, 14,106, +106,106, 28,234,200, 28, 14,161, 87,216,105,242,191,172,197,143, 82, 53, 0,224,203, 85,167,236, 30, 35,232, 62,177,112,225,194, + 48,138,162, 16, 53, 41,106,250,161,164, 67,191, 50, 37,126, 83, 81, 47, 78,125,225, 58, 65, 16,189, 40, 10,224,190, 44, 3, 69, + 81, 88,178,116, 9,218,140,111,219,194,188,170,250,101,189,116,187, 99, 51, 9, 62,126,104,110, 21,128,113,240, 54, 91,198, 70, + 37, 38, 38,218,237, 50, 53, 33,109,167, 60,184,169, 60,122,253,255, 83,186,188,238,137,128, 89,221, 55, 89, 34,102,229,218,125, +131,129, 88, 44,214, 74, 36,146,253,163, 71,143, 94,148,156,156,188, 78,171,213,162,182,182,214, 24, 3, 0, 0, 21, 21, 21,168, +173,173, 5, 69, 81,176,167, 61, 69, 68, 68,136,142, 31, 63, 46, 77, 76, 76,108, 98,125,210,159,143,136,136,176, 43, 25,208,131, +128,226,220,219,142, 16,254,125, 4,111, 99,200, 38, 8,130,160, 28, 33,127,131,167, 45,205, 82, 95, 4, 0,147,160, 64, 70, 88, +176, 96,129,148,193,119, 50, 54, 52, 76,167, 42,239, 39, 34,102,201,241,186,118,237, 74, 93,191,126,157,118,249,127, 10,224, 19, +149, 74,133,188,188, 60,200,100, 50, 71,169,144, 34,247,248,225,216,101,253, 74,189, 29, 82, 53,118,159, 83,131,162, 40,156, 62, +239, 56, 39,166,167,167, 99,194,132, 9,162,195,135, 15,167, 29, 74, 58,228,168, 24, 14, 73,146, 46, 0,176,231,188, 6,139, 23, + 47, 70,155,200,182,204,213, 73, 11,104,108,108, 4, 0,228,231,231, 83, 91,182,108, 49, 42,100,166,177, 36, 59,118,236, 48, 29, + 31, 88,247,130, 19, 65, 91,247,150, 44,127,243,235,205, 77, 1, 16,134, 41,128,251,150, 77,217, 51, 5, 96,113,160,112, 30,233, +152,202,115,234,250,127,122,238,223, 81,216, 82, 72,236, 85, 88,172,185,251, 29,157, 6,176,230,238,119,112, 26,192, 52, 40,136, +176,227, 26, 44, 40, 1, 20,128,245, 18,137,100,115, 66, 66,130,134,207,231, 67,165, 82, 65,171,213,130, 36, 73,248,250,250,162, +166,166, 6,246,102, 83, 60,126,252,120, 26,244,235,254,169,125,251,246,193,160, 8, 24,151, 6, 30, 63,126,252,127, 98,112,120, +233,165,151,168,198,198, 70, 28, 58,116,200,222,246, 44,180, 81,223,212,204, 27,209, 34, 38,222,184,247,223,127,255, 62,227,194, + 28, 31,124,240, 1,197, 52,200, 83, 44,246,179, 41, 79, 44,246, 99, 36,204,205,205,141, 30, 36, 41,138,162, 32,151,203, 81, 90, + 90,234,240,156,191, 41, 34,191,168,111,114,222, 18,242,215,233,116, 4, 0, 56, 96,241,155,131, 60,248,123, 82,119,211, 76,128, +206, 66,115, 10,153,137, 2,192,226,113,244, 0, 24, 94, 28, 97, 79,249, 35,182, 64,211, 30,179,231, 33,236,176,152,109, 40, 34, +227,156,246, 92, 51,103,206, 20, 57,144,222,183, 89, 11,205,130, 5,218,156,117,202, 40,104, 76, 44, 22,107, 1, 16,211,167, 79, + 23, 22, 22, 22, 74, 21, 10, 5,116, 58, 29,122,245,234, 37, 26, 52,104,144,195,239,123,223,190,125,166, 75,206, 28,242, 26, 61, +232, 24, 0, 91,231, 76,244, 69, 67,116,120, 83,194, 57,125,218,110,183,191, 97,173, 63, 53,243,198,253, 10, 28, 69, 81, 20,157, + 35,192, 68, 33, 51, 6,204, 57,218, 55, 0, 96,239,222,189,132,179,250, 26,211,123, 0,160,186,186, 26, 93,187,118,165,234,234, +234,208,185,115,103,100,103,103, 59,101,172,227,188, 84, 3,130, 32, 48,229,133, 88,218, 13,131,213,171, 22, 24,255,183, 55, 99, +166,179, 32, 22,139,201,205,167, 54, 59, 85,230,156, 57,115, 12, 94, 23,137, 39, 0,173,225,160,196, 98, 49,105,114, 15, 59, 29, +240,184, 43, 0, 79, 16, 90,220, 73, 31, 87, 55,148,179,159,235, 1,120, 97, 30,104,189, 25,230,248,141,223,113,227,198,141, 71, +252, 70, 72,226,241,150,167,175, 43,123, 51,202, 89,197, 39, 77,246,177,160, 44, 93, 51, 88,222,105, 79,195, 64, 82, 86, 86,102, +124, 31,249,249,249, 78,123, 39, 18,201,102, 74, 44, 94, 64,252,254,155,132,209, 7, 28,221,222,213, 17, 24,150,245, 57,125, 76, +104, 78,185,102,221,254, 15, 31,150,166, 6,136,135,217,208, 88,176, 96,193,130, 5, 11, 22,143, 7, 56,108, 21,176, 96,193,130, + 5, 11, 22,172, 2,192,130, 5, 11, 22, 44, 88,176, 96, 21, 0, 22, 44, 88,176, 96,193,130, 5,171, 0,176, 96,193,130, 5, 11, + 22, 44,158, 10, 52, 89, 5, 64,231,188,118, 4,150,130, 9, 89,121,172, 60, 86,222,195,147, 23, 23, 23,215, 84,187,231,112,140, +217,229, 76,151,154,209,217, 20, 77,151,158, 89, 74, 31,236,233,233, 9,129, 64, 96,252, 60,135,195, 1,151,203,189, 79, 30,189, + 49, 19, 73,234, 87,121, 89,219, 44,135,125,191,214, 33,145,108, 17,114,121,174,160, 72, 45,230,207,127, 35,205, 17,121,155, 55, +111, 22,101,103,103,243,194,194,194, 82,205,179,238, 57, 40, 79,152,157,157,141, 77,155, 54,165,177,253,237,201,147,103,183, 2, +240,191,136,192,192, 55,154, 84, 92,101,229,118,226,177,146,247, 70, 32, 5, 0,149,219, 43, 9,211,255, 91, 32,178,133,201, 61, + 31,184,188,255, 89,108, 93,183, 70, 88,113,245, 28, 70,249, 85, 72,219,107,139,144, 67,117,197,133, 70,127,145,119,232, 16, 44, + 90,186, 44,205,214,231,207,156, 57,131, 17, 35, 70, 24,137,159, 38,108,130, 32,238, 35,108,146, 36,141,199,157, 59,119, 44,202, +187,120,241, 34,194,195,195,225,230,230, 6, 30,143, 7, 46,151,219, 68, 38, 77,250, 58,157,206,120,168, 84, 42,100,102,102, 34, + 36, 36,228,169,123, 63, 18,137,132, 16,139,197,212,230,205,155,133,127,255,253, 55,110,221,186, 37,245,245,245,197, 47,191,252, +210,162,246,191,101,203, 86,161,171,192, 31,190,126,207, 72, 27, 27, 74, 68, 91,182,108, 19,110,220,104, 95,238,135, 77,155, 54, + 9, 19, 19, 19, 79,230,228,228,224,208,161, 67, 8, 13, 13,197,123,239,189,199, 53, 93,123,239,128, 60,105,126, 94, 46, 66,130, +187,129,239,234,138,197,139,151,140,137,141,141,101,183, 2,126, 90, 61, 0, 79, 18, 34, 34, 34,108,106, 60,199,143, 31,183,217, + 49,105,130, 54, 39,110, 71,225,108,121, 15, 0,132,157,164,109, 51,181,172,147,229, 49,249,188,249,247, 63,217,196,178,121,179, +240,250,153, 99, 40,220,253,141, 84, 46, 87, 65, 51,132, 3,183, 14, 4,186, 23, 94,198,179, 94,148,180,166,226, 47,180,219,252, +255, 68,211, 23,124,214,172, 18,112,253,250,117,112,185, 92,140, 28, 57, 18, 60, 30,207,120,208, 10, 1,109,245,107,181, 90,232, +116, 58,104, 52, 26,220,185,115, 7, 39, 79,158,180, 40, 79, 46,151, 35, 43, 43, 11, 67,135, 14, 5,159,207,135,139,139, 75, 19, +153, 36, 73, 66,171,213, 66,171,213, 66,163,209, 64,161, 80, 32, 43, 43, 11, 13, 13, 13,143, 3, 89,115, 12,109,131, 3, 64,219, +146, 60,244, 18,137,132,136,139,139, 35,227,226,226, 16, 16, 16,128,127,255,251,223,152, 49, 99, 6,234,235,235, 17, 16, 16,224, + 80, 6,210,128,128, 0,227,243,124,244,209,135,248,121,103, 38,220,220, 90,129,203,229, 75, 27,234,139,236,150,153,145,145,129, +134,134, 6, 12, 29, 58,244,206,184,113,227,218, 86, 85, 85,225,216,177, 99,186,249,243,231, 99,235,214,173,205,246, 17, 85, 65, +238,125,117,115,229,230, 77,164,121,185, 99,105,252,103, 69, 3, 6,246,233,120,183,184, 28,199,146,211, 78,238,218,181,123, 92, + 76,204,203, 39, 88,234,124,252, 65,167,254, 53,243, 20, 48, 82, 0,204, 83,183,218, 58,127,232,228,255,230,155,111, 54,123, 79, + 77, 77, 13, 0, 80, 76,148, 0,154,172, 91,106,173, 63, 8,121,166,150,191, 19,172,127,123, 73,155, 41, 89, 59, 91,158,233,189, +166,127, 1, 0,213,213,250,204,136,254,254,169, 79, 69, 71, 45,248, 51, 21, 33, 69, 82,105,145,156,196,180, 16, 46,158, 9,210, +130,244,167,224,226,207, 69,125, 21, 31,110,245, 10,244,204, 94, 47,253, 57, 62, 78,244,234,146, 21, 86,149, 0,130, 32,112,227, +198, 13,240,249,124,140, 25, 51,198, 72,218, 46, 46, 46,224,112, 56,160, 40, 10, 26,141, 6, 90,173, 22, 42,149, 10, 69, 69, 69, +144, 74,165, 86,183, 84,230,112, 56,208,104, 52,200,206,206,198,200,145, 35,225,230,230, 6, 87, 87, 87,163, 60, 90, 1, 80,169, + 84,104,104,104,192,149, 43, 87,160, 84, 42,141,211, 4, 76, 16, 19, 19, 35,228,114,185,210,250,250,122,240,249,124,148,151,151, +191, 61,109,218,180,122,129, 64,240,179, 35,164, 29, 19, 19, 51,147,203,229,238, 73, 78, 78,166,229,229, 76,155, 54,237,111,137, + 68, 50, 67, 44, 22,171, 29,177,132,227,226,226,164, 43, 86,172, 40, 7,208, 10,208, 79,181, 92,191,126, 29,173, 90,181, 66, 88, + 88, 24,126,250,233, 39,187,201,255,135,185,115, 49,113,192, 0, 0, 64,155, 69,139,224,230,222, 26, 13,117,133,168,147,229,137, + 98, 99,231,165, 89,203,231,110, 13,253,250,245, 67,121,121, 57,206,156, 57,211,153,195,225,224,202,149, 43,240,247,247, 71,122, +122, 58, 94,123,237, 53, 42, 59, 59,187,217,207, 87,125,181,180,201,185,167, 90,131,118, 90, 37, 22,191,255, 73,199,248,213,255, +193, 55,171, 55,162, 61, 71,135,141,171,215,164,190,246,218,107,176, 37,143,197,227, 71,254,116, 57,211,189, 0,238,203,255,109, +235,252, 97,194,153, 59,245, 61, 9, 48, 85, 2, 30,146, 39,192, 94, 75,157,176, 97,157, 59, 34,207,210,223,167, 42,113,213,119, +171,190, 20,134,102,255, 32, 45,231,234, 16,226, 3,116,238, 68,129,219,143, 15, 94,183,110,224,171,148, 80,157, 45,130, 74,198, + 3,151,116,129, 50,245,103,233,214, 13,171, 69,243,223,178, 60, 29, 64,187,231,115,115,115,225,231,231, 7,145, 72, 4,129, 64, + 0, 62,159, 15, 30,143,103,180,250,149, 74, 37, 74, 75, 75,113,234,212, 41,112, 56, 28,112, 56, 28, 52, 39, 79,167,211,225,218, +181,107, 24, 49, 98, 4,188,189,189, 33, 16, 8,192,229,114,161,213,106,161, 86,171, 81, 87, 87,135,191,254,250, 11, 42,149, 10, + 60, 30,207, 24, 11, 96, 11, 35, 71,142, 20,222,188,121, 83,122,251,246,109,212,213,213,129,207,231,163, 77,155, 54,235, 79,159, + 62,141, 97,195,134,241, 36, 18,201,143,246, 40, 1, 35, 71,142,156,122,243,230,205, 61,102,242, 66, 79,159, 62, 29, 58,108,216, +176, 93, 6, 37,128,145,188, 77,155, 54, 9,213,106, 53,202,202,202,104,151,183,177,146, 86,172, 88, 81, 18, 23, 23,215,126,198, +140, 25, 99,222,125,247, 93,187,198,191,173,219,126, 20,126,184,124, 89,147,178,178,117,235,208,230,197, 14,248,230,155,239, 68, +115,231,190,226,208,120,122,230,204, 25,233,159,127,254,137, 15, 63,252,176,142,203,229,122, 11, 4, 2, 12, 27, 54, 12, 82,169, + 20,201,201,201,104,223,190,189, 29, 61,143,192, 47,185,119,177,255, 86, 9, 14,254,254, 19,184, 92, 2, 75, 23,189, 74,246,111, + 19,200,217,178,248, 19,108,181, 87, 30,139, 71, 66,254,230, 74,164, 37,165,192,225, 85, 0,143,122,123,219,110,221,186,137,108, + 29, 15,219, 90,127, 16,242,156,104,245, 51, 37,109, 71,200, 26,166,214, 57,109,161, 27,228, 80, 14,202,179, 58, 80,251,251,167, + 58,100,253,111,216,176, 65, 56,111,222, 60,202, 90,153,249, 53,107, 48,189,127,195,134, 13, 66,243,107,230,101,205,214,215,181, +139,210,210,146, 58,180,242,226,161,155, 23, 5, 94, 32, 9,222,115,207,195,163,255,207,112, 27,248, 45, 92,125,220,192,111, 80, + 64, 46,215,161, 19, 87,142,244, 4,235,169,100, 57, 28, 14,120, 60, 30, 92, 92, 92,112,235,214, 45, 92,185,114, 5,222,222,222, + 8, 8, 8, 64, 64, 64, 0, 2, 3, 3,225,235,235, 11,153, 76,134,244,244,116,112,185, 92,227,220,190, 37,208,215,249,124, 62, +116, 58, 29,114,114,114,224,238,238,142,192,192, 64,180,106,213, 10, 65, 65, 65,240,244,244, 68, 78, 78, 14, 52, 26,141,113,138, +192,154, 66, 97,110,249,223,187,119, 79,154,151,151,135,174, 93,187, 34, 50, 50, 18,131, 7, 15,134, 92, 46,199,201,147, 39,145, +157,157,189, 93,169, 84,190, 98,135,229, 47,186, 87, 94,241,107,254, 93, 25,188, 66,134, 34, 52,242, 13,180, 31, 60, 5, 53, 42, + 14,142,167,158, 64,118,118,246, 52,165, 82, 57,159, 41,249,215,213,213,225,242,229,203,210, 51,103,206,160, 95,191,126,136,139, +139, 11, 4, 64, 26, 60, 0,237, 1, 64, 32, 16, 48, 38,235,173,219,126, 20,254,146,144, 36,244, 15,232, 35, 77,216,125, 25,115, +127,248, 1,201, 89, 89, 72,206,202, 66,155, 69,139, 0, 0, 26, 77,227, 41, 71,250,220, 11, 47,188, 64, 29, 60,120, 16,211,167, + 79,191,227,229,229,197,113,119,119,207,204,200,200,192,153, 51,103, 80, 89, 89,137,208,208, 80,251,148,210,172, 91, 88,253,199, + 85,108, 93,253,209,101, 30, 87, 1,142,174, 30, 95,175,253,129,179, 39, 61, 19,165, 28, 30,158,121,230, 25,150,101,159, 18,240, + 28, 37,248, 71,181,121,197, 3,179,176,255,183, 21,129, 7, 50,175,222, 66, 87, 61, 97,163,220, 46,165, 98,245,234,213,194, 19, + 39, 78, 72,115,115,115,173,150,101,100,100, 48,146, 69,223,151,145,145,129,234,234,106,233,234,213,171, 69,203,150,233,173,114, + 75,101,205,193, 91, 89,133,228, 66, 37,218,215,112, 49,192,155, 64, 80, 5, 16,194,243, 1,135, 8, 0,165,188,135,198,123, 4, +174, 21,146, 40,107, 84,130,199,225,160,175,191,171,212,218,239, 54, 85, 0, 92, 93, 93,145,151,151,135,246,237,219, 35, 34, 34, + 2, 92, 46, 23, 36, 73,162,170,170, 10,103,206,156,129,139,139, 11,248,124, 62,212,106,181, 85, 5,128,246, 14,208, 74, 0, 69, + 81,200,207,207, 71, 72, 72, 8,124,124,124,208,208,208,128,172,172, 44,232,116, 58,184,186,186, 66,165, 82, 65,165, 82, 89, 29, + 59,232, 32, 58, 0,168,168,168,144, 22, 23, 23,163,127,255,254, 16, 10,133,232,208,161,131,168,177,177, 17, 65, 65, 65,210,212, +212, 84,156, 63,127, 30,190,190,190, 67, 37, 18,201, 78,177, 88,172,179, 85,143, 21, 21, 21, 39,239, 85,203,224, 31, 58, 20,221, + 70,190, 4,223, 14,161, 80, 53,214,162,240,207,195,184,117,226, 39, 90, 30,163,247,107,136,125,144,150,150,150,162,117,235,214, + 16, 8, 4,162,203,151, 47, 75,227,226,226, 56, 6, 15, 0, 0,220,140,139,139, 35,153,180,193,109,219,127, 18,250,250, 61, 35, +245,245,127, 6, 28,142, 11, 52,154, 70,108,255, 81,138,185,175,139,104,143, 2,230,207,159,143,160,160, 32,210,222,190,247,234, +171,175, 82, 9, 9, 9, 24, 57,114, 36, 6, 14, 28,216, 25,128,246,196,137, 19,225, 5, 5, 5,112,115,115,131,155,155, 27,162, +162,162,198,236,221,187,247, 36, 19,121, 59,255, 46,194,183,127,221,196,182,149,203,171, 59, 60,211,185, 95, 99, 67, 13,126, 63, +242, 23, 46, 95,249, 27,190, 20, 9,126,217, 61, 68,189, 61,123,220,158, 61,123,255,183, 92,176, 79, 16, 44, 77, 31, 89,243, 10, + 88, 83,213,137, 25, 51,102,152, 90,208, 68,116,116,116,115,231, 79, 44, 42, 43,183, 19,166,199,227, 38, 15,120, 32,238,255,230, +172,246, 22, 61,179,163,214,185, 61, 30, 0,123, 17, 19, 19, 35, 76, 74, 74,106, 66,254,150,202, 28, 65,110,110, 46,146,146,146, +164, 49, 49, 49,194,230,202,172, 18, 87,101, 17,206,221, 85, 64,174, 35,113,186,136, 68,153,150, 7,157, 42, 19, 53,215,223,196, + 79,139, 98,113,232,152, 12, 87,170, 40, 92,170,208,226, 90,149, 22, 85,165,101,205,122,229, 76,149, 0,129, 64,128, 59,119,238, +224,230,205,155, 0,244,113, 49,127,100,194, 62, 90, 0, 0, 32, 0, 73, 68, 65, 84,252,241, 71,147,185,252,230,230,235, 9,130, + 48,122, 1,104,121, 20, 69,161,168,168, 8,157, 58,117, 66,105,105, 41, 72,146,132, 64, 32, 48,202,106,110, 74,193, 20,133,133, +133, 80, 42,149, 8, 15, 15, 71,135, 14, 29, 68, 92, 46, 23,222,222,222, 24, 50,100,136,200,211,211, 19,133,133,133,168,171,171, +187,194,180, 29, 20, 22, 22,130,228,240,209, 62,108, 28,124, 59,132,130,195,117,129,155,119, 16, 58, 13,137, 2,223,195,143,150, + 87, 96, 75,206,230,205,155,133,181,181,181,210,146,146, 18,116,236,216, 17, 34,145, 72,244,243,207, 63,167, 85, 85, 85, 17, 0, + 48,116,232, 80,173,225,214, 80, 31, 31, 31, 72, 36, 18,155, 1, 15, 2, 65, 0, 2,130,250, 67,167, 85,161,252,110, 6,202, 74, +206,140,173,172,200,250,200, 32, 15, 0,112,175,172, 12, 6,121, 46, 76,219,158, 88, 44,158,145,144,144,128,217,179,103, 99,214, +172, 89, 0, 64, 30, 59,118,140,151,148,148,132,185,115,231,142,191,120,241, 34,113,246,236, 89, 34, 46, 46,142, 81,228,126, 78, +157, 28,203, 79, 93,194, 87,239,197, 98,228,164,113,254, 58, 74,139,189,191,158,194,247,235,127,198,145, 37,175, 97,107,255, 78, +232,228,195,195, 71, 31,197,177, 65,128, 79, 8, 46, 93,186,100,149,252,155,245, 0,152,207,237,219, 58,127, 26,241, 0,150,224, + 57,132, 47,158,253, 66,180, 96,193,130, 39,161,190,155, 76, 41, 60,224, 32, 61, 70,239, 33, 42, 42, 74,120,235,214, 45,169, 90, +173,110,182,172, 37,168,169,169, 65, 99, 99,163, 52, 42, 42, 74, 84, 84, 84,116, 95,217,225,195,135,173,190,187,236,106, 5,100, +106, 18,217, 21, 90,148,214,106,209,250, 15, 30,250,237,205,197,157,130,107,248,251, 79, 53,180, 60, 46,212, 36,160, 84, 83,168, +161, 72, 4, 53,179,173, 61,189,220,143,158,187,167, 35,246,239,221,187,135,206,157, 59,163,160,160,192,232,242,231,241,120,198, +251,237,157,206, 51,205, 33, 64,255,125, 64, 83,130,181,112,110,204,135, 77,178, 38, 73, 18,141,141,141,250,193,145,199, 19,189, +249,230,155, 77,222, 93,125,125, 61,239,224,193,131,152, 50,101, 10,103,249,242,229,247, 86,173, 90,165,181,213, 22, 9, 66,175, + 16, 41,228,247,208, 80, 95, 36,154, 55,239,181, 52,137, 68,146, 14,224,171,250,250,122, 28, 60,120,208,168, 56,134,132,132,168, +153,180,237,149, 43, 87, 78,249,230,155,111, 18,163,162,162, 48, 98,196, 8, 0, 32,207,158, 61,203,249,237,183,223, 32, 20, 10, + 39,109,216,176,225,184, 61, 21,115, 87,174,194,171,201,127, 96,241,204, 40,204,120,117, 58,228,202, 58, 28, 56,152,134,181, 27, +119,226,191,227,159, 69,183,242, 98,150, 77,159, 2,101,128,169, 7,192,217,160,204, 58,178,173,115, 22, 38,120,208,228,239, 68, +171,221,154, 71,193,209,249,255,230,218, 5,163,246,114,248,240,225,180,238,221,187,139,252,252,252,154, 45,107, 9,252,252,252, +208,189,123,247, 38, 68,111,169,204, 18, 20, 58,111,104, 8,224, 66,165, 10,229, 58, 29, 78,228, 43,177, 55, 81,137,147,197, 65, +200,229,251,160, 88,166, 65, 81, 61,137, 70, 45, 32,215, 82,112, 13,104, 99,147,152,233,245,253, 58,157, 14, 90,173, 22, 1, 1, + 1,240,244,244, 68,231,206,157,161,209,104,140,229,150, 18, 2,153,203,163,215,247,107,181, 90, 40, 20, 10, 80, 20,133,142, 29, + 59,162,164,164, 4,109,219,182, 5,143,199,131, 74,165,130, 90,173, 54,126, 47,147,233,193, 78,157, 58, 65, 32, 16, 32, 51, 51, + 19,197,197,197, 82,157, 78,135,186,186, 58,226,207, 63,255,148, 54, 52, 52,160, 83,167, 78,240,246,246,126,158,233, 24,213,169, + 83, 39,112, 72, 53, 74,178, 82, 81, 91,156, 3, 82,167,129,162,174, 2,133,127, 30,134,186,177,134,150,215,133,137,114, 67, 35, + 32, 32, 64,186,105,211, 38,163, 23,167,170,170,138,184,118,237, 26, 12,164, 77, 2,104,109, 41,225,145, 57,180, 90, 5,180,154, + 6,184,121,180,129,192,205, 31, 18,201, 22,161, 88, 44,214,174, 88,177, 34,192, 68, 30,182,110,221, 10,153, 76, 70, 47, 97,188, + 15, 43, 86,172,160,134, 15, 31, 78, 13, 28, 56,144,250,236,179,207,126,159, 50,101, 10, 38, 77,154, 4, 0,184,120,241, 98, 93, + 82, 82, 18,102,204,152, 49,229,196,137, 19,135,153,212,217,138, 21, 43,168, 17, 35, 70, 80, 47,191,249, 54,198,236, 59,133,101, +255,154,134,119, 62, 88, 8,165,186, 1,183,243,138, 32,145,236,197,111,147,135, 65,216,177,149,195,125, 99,194,132, 9,236,184, +254, 8, 17, 22, 22,214,132,244,205, 3, 1, 31,106, 42,224,232,232,104,161, 61,231, 15,205,210,183,178,102,223,220,218,103,106, +253, 91,147,247, 70, 96, 32,245, 70,224, 63,238,124,243,115, 91,158, 8,103,201,179, 98, 73, 59, 66,212, 15, 12,102, 74,132,195, + 30, 0, 0,216,181,107, 87,218,228,201,147, 69,166,201,105, 44,149, 57,130,144,144, 16, 76,158, 60, 89,180,107,215,174,180,230, +202,172,126,190,123, 8,186,123,112,225, 69, 0, 26,138,194,141, 26, 53, 18,114, 85,216,117,174, 20,127,229, 85,163, 84, 1, 84, + 41,117,200,107,160,112, 87, 69,161, 65,173, 17, 53, 71, 94,244,210, 60,181, 90, 13,133, 66,129,182,109,219,162, 79,159, 62, 6, + 69,207, 31,131, 7, 15, 54, 18, 54, 77,218,214, 8,155, 38,116,141, 70, 3,181, 90, 13,130, 32, 16, 28, 28,140,218,218, 90, 20, + 21, 21,161,186,186, 26, 93,186,116, 1,135,195,129, 90,173,134, 74,165, 50,126,198, 22,130,130,130, 68, 29, 58,116,192,181,107, +215,112,244,232, 81, 28, 58,116, 72,122,232,208,161,147,167, 79,159, 6,151,203,197,115,207, 61,135,110,221,186, 41, 96, 8,188, + 99, 32,111, 74,107,127, 31, 84,229, 95,194,223,199,127,196,181,195,155,112,227,176, 4,119,206,255, 6, 87, 14, 73,203, 43,177, + 37,231,173,183,222, 74,107,221,186,181,200,219,219, 27,217,217,217, 40, 46, 46,150,198,199,199, 11, 77, 21, 1,131, 39,128,147, +144,144,128,222,189,123,219,124, 54,181, 74, 6, 89,109, 46, 92, 92, 60,224,235,223, 67,234,225,217, 30, 63,252,240,139,144, 32, + 56, 67,233,123,188,106, 83, 33,253,239, 59,136,232,209, 96,181,109, 31, 62,124, 24,110,110,110,232,221,187, 55,186,116,233, 66, + 79, 31,104,107,106,106, 26,246,237,219,231, 27, 22, 22, 54,101,207,158, 61, 73, 76,219,110,114,242, 97,120,123,123, 98,212,232, + 33,242,176,129,253, 48,245,205,185,144, 19, 90, 84,148, 87, 99,193,162,207,177,106, 80, 8, 6,182,114, 92, 73,158, 48, 97, 2, +245,245,215, 95,179, 74,192, 99,162, 8, 88,194, 99,179, 23,192,163, 94, 85,224, 8, 1,219,139,237,149,122, 5,194,148,168,233, +178,199, 65,222,227,234, 81, 48,243, 4, 80,246,120, 0,104, 44, 91,182, 44,109,236,216,177,162,193,131, 7, 91, 45, 51,189,214, + 28, 76,239, 31, 59,118,108,147, 96, 63, 75,101,205, 90,135,174, 30,162,190,109, 3, 49, 60,192, 21,207,250,241,209, 78,192,129, + 43, 69, 65,160,210,162,147, 39, 15, 53, 20,133,171, 13, 90,228, 52,106,209,190, 85, 0,186, 60, 59,218,170, 44,218,234,167,151, +250,117,234,212, 9,253,251,247, 71, 77, 77, 13,106,107,107, 81, 91, 91, 11, 47, 47, 47, 12, 29, 58, 20,106,181,218,152, 19,192, + 26, 97,211,202,132, 70,163, 1, 65, 16, 8, 13, 13,133, 66,161, 64, 69, 69, 5,202,203,203, 81, 81, 81,129,198,198, 70,132,134, +134,130,199,227, 25,229, 89,203, 43, 96,174,148,181,110,221, 90, 20, 28, 28,140,219,183,111, 35, 37, 37, 5, 25, 25, 25,112,119, +119,199,152, 49, 99,208,191,127,255,195, 2,129, 96, 41,211,101,123,187,118,237, 74,106,221, 42,232,149,224,182,190,104,200,251, + 19, 57, 41,219, 81,146,241, 59,252, 92,117, 24, 55,118, 12,250,247,239, 63,231,221,119,223, 61,200, 68,150,183,183, 55, 6, 14, + 28, 8,138,162,112,238,220, 57,100,102,102, 74, 75, 74, 74,164, 95,125,245,149, 48, 46, 46, 78, 68,103, 78, 28, 52,104, 16,210, +211,211,109,202,155, 63,127,110,154,172, 38, 87, 84, 93,113, 5,174, 2,127,180,105,247,156, 52,168,205, 96,169,151,119,151,195, +223,172,254,126, 50, 45,111,215,187,238,216,125, 86, 5,107, 74, 79, 78, 78, 14, 2, 3, 3, 49, 98,196, 8,242,217,103,159,133, + 92, 46, 71, 99, 99, 35,214,175, 95,239,217,163, 71,143, 23,165, 82,105,146, 61,125,226,239,191,115,208,185, 83, 7,188,252,242, + 20,247,143,255,189, 24, 85,245, 50, 84, 86, 85, 34,246,157,207,241,249,212,177, 24,219,169,117,139,200,127,237,218,181,232,211, +167, 15,214,173, 91,199, 42, 1, 15, 17,166,243,254,182,240,208, 50, 1, 58,115, 85,129, 33,185,143, 83, 50, 1,218,130,121, 34, + 30,103, 40, 1,206, 36,107,103,203,115,198,171,134, 19,210, 3,155, 41, 16,132, 21,143,133, 93,120,235,173,183,210,204, 63,103, + 90,182,109,219, 54, 70, 50,233,251, 44,221,207, 84, 6,141, 29,187,246,164, 45,127,117, 38,180, 25,201, 40,144, 1,158,132, 11, + 58,123,114, 80,162, 35,192,117,229, 33,189, 92, 7, 37, 9, 4,185,114, 17, 60,104, 20,222, 93,189, 53,173, 57, 5, 64,163,209, +128,203,229,162,107,215,174, 24, 56,112, 32,234,234,234,160, 84, 42,141,235,243,213,106, 53,252,253,253, 49, 98,196, 8, 36, 37, + 37, 25,167, 4, 44, 65,167,211, 25,179, 8,246,236,217, 19, 6, 55, 61,148, 74,165,177, 63,211,158,132,158, 61,123,162,186,186, + 26, 13, 13, 13, 86,251,178, 57,153,159, 62,125, 58, 45, 38, 38,102, 76,239,222,189, 79,154, 36, 2,170, 29, 57,114,228, 73,129, + 64, 48, 91, 44, 22, 43,237,169,203,211,167, 79, 39,196,196,196,212,245,238,221,251,160,137,188,202,145, 35, 71,174,127,247,221, +119, 25,103,235, 89,184,112, 97,218,166, 77,155, 68,145,145,145,184,125,251,182,244,230,205,155, 40, 44, 44,132,151,151,151,212, +215,215, 23, 17, 17, 17,216,182,109, 27, 6, 13, 26,196,248,217,222,120,227,213,180,109,219,118,136,148,202,106,248,250,133, 74, + 61,189, 58,194,203,187, 19, 26,235, 75,146, 86,174,218,142,152,151,199, 97,215,187,238,198,122,178,100,177, 77,156, 56, 17,201, +201,201, 40, 46, 46,230, 84, 87, 87, 67,169, 84, 34, 61, 61,157,103, 80, 58,235,206,158, 61,107, 87,127,136,138,154,136, 3, 7, +146, 80, 87, 91,133,226,210,187,120,247,173,127,169,223,255,112, 5,127,234,152, 97, 24,161,170, 3, 92, 28,163,135, 9, 19, 38, + 80,159,126,250,169, 49, 29,116,112,112, 48,190,254,250,107, 0,160,142, 28, 57,194,166, 13,127, 68, 74,193,163, 84, 0,136, 25, + 51,102,152,186,208, 8, 51,119, 63, 97,175,251,223, 25,228,110, 36,249,202,237,176,149,109,207,158,224,191,202,202,237, 48,117, +197,155, 18,179,185,203,158, 9,105, 87,110,175,116,170,188, 39, 0,255, 83,131, 68,151, 97, 34,209,101,149, 86, 90,113,242, 4, + 92,180, 10, 92,174,167,144, 90,175, 5,159, 32, 16, 64, 81, 16,181,245,133, 95,155, 32, 81,135, 33, 66, 96,199, 30,155, 30,128, + 46, 93,186, 96,240,224,193, 80, 40, 20,208,104, 52,224,243,249, 70,194,166,173,244,160,160, 32, 12, 31, 62, 28, 41, 41, 41,205, +122, 0,120, 60, 30,250,247,239, 15,130, 32, 32,151,203,141,222, 5, 90,105,167,179, 11,146, 36,137,190,125,251,226,143, 63,254, +128, 61,193,149,187,118,237,146, 2, 32, 36, 18, 9, 1,192, 19,250,108,123,133, 98,177, 88,227, 72, 93,238,218,181, 43,201, 32, +207, 19,128, 63,128,106,177, 88,108,119,110,226,133, 11, 23,166, 1,192,134, 13, 27, 68, 46, 46, 46,200,207,207,135,191,191,191, + 20, 0, 74, 74, 74, 48, 97,194, 4,172, 89,179,198, 46,153,243,230,205, 73,147, 72,182, 8,213,106,153,200,173,174, 64,234,237, + 27, 12,119,207,118,112,247,108,135, 99, 39,238,129, 24,219,188,197,253,211, 79, 63, 17,243,231,207,167,170,171,171, 49,113,226, + 68,117, 64, 64, 0,159, 36, 73, 20, 22, 22,218,237, 17, 3,128, 29, 59,126, 34,196,226, 88,202,251,122, 38,222,122,235, 13,116, + 8,237,206,255,122,241, 27,228,142,141, 63,113,214,115,149, 14,181,229, 9, 19, 38, 80,203,151, 47,135,175,175, 47, 74, 75, 75, +225,230,230, 6,146, 36,225,225,225,129, 47,191,252,146, 85, 2, 30, 2,194,194,194,172,122, 1,152,166, 2,118, 58, 30,243, 85, + 5, 68,229,246, 74,139, 23, 28,180,254,137,237,149,247,203, 51,183,212,105,215, 61, 3,210,118,182, 60, 22,143, 17, 12,100, 67, +188, 20, 53, 65,232,163, 85, 73,185,119,242, 17,162,185, 11,175,128,214, 24,214,183, 7, 2,218, 7,138, 62,216,180, 51,109,119, +198, 66,155, 94,180,174, 93,187, 98,196,136, 17,198,249,120, 46,151, 11,149, 74,101, 76,221,107, 58, 77,208,177, 99, 71, 12, 31, + 62, 28,105,105,150,187,158,155,155, 27,194,194,194,192,227,241,160, 86,171,141,159, 51, 93, 58,104,186, 17, 16,135,195,193,128, + 1, 3,144,153,153,105,119, 29, 24,188, 3,245,134,163,197, 48,144,126,139, 55, 37, 48,120,136,140,253,112,211,166, 77, 66,185, + 92, 14,149, 74,133, 30, 61,122, 32, 62, 62, 94,106,223,115,197,166, 1,128, 68,178, 69,164, 80, 84,192,213,213, 15, 46,124, 47, + 41,135,195,195, 47, 9,135, 69,175,204,142,106, 86,222,214,173, 91, 9,137, 68, 66,124,251,237,183,164, 66,161, 0, 0,132,134, +134,218,149,126,217, 20, 18,201, 22, 98,219,182,173, 19,230,126,250,109,178, 94, 30,197, 9, 13,125, 6,161, 47,190,248,202, 91, +111,189,149,224,136,204, 85,171, 86,177,157,250, 49, 81, 2,154, 35,255,135,170, 0, 60,169,112,230,178, 63,115, 98,110, 41, 81, + 59, 81,158,179, 21, 6, 86, 1,113, 0,123, 14, 31, 73,107, 82,119,117,133, 56,125,187,144,241,231,163,163,163,225,231,231,103, +140,240, 39, 73,210,232,194,167, 61, 0,116,208, 31,189, 35, 96,112,112, 48, 8,130,192,238,221,187,239,147,183,118,237, 90, 36, + 38, 38, 26,239,213,233,116, 54,183, 3,230,243,249, 24, 52,104, 16,152, 68,199, 63,193,202, 90,139,219, 58,173, 8,232, 73,125, + 59,244,225, 88,164,148,137, 60,131,178, 68, 0,192,166, 77,155,168,133, 11, 23, 18, 39, 78, 56,190, 52,127,222,188,249, 71, 12, + 94, 19, 14, 73,146, 58, 14,135,227,102,239,244, 11, 13,214,186,127,188,148, 0,155, 3,181,163,251, 8,179, 96,193,130, 5, 11, + 22, 44,158, 92,112,216, 42, 96,193,130, 5, 11, 22, 44, 88, 5,128, 5, 11, 22, 44, 88,176, 96,193, 42, 0, 44, 88,176, 96,193, +130, 5, 11, 86, 1, 96,193,130, 5, 11, 22, 44, 88, 60, 21,104,178, 10,224,210,165, 75, 14, 71,112, 90, 10, 38,100,229,177,242, + 88,121, 79,165, 60,234,133, 23,197,248,253, 55, 9, 36, 18, 9,199, 82,182, 62,182,254, 88,121,157, 58,117, 50,222, 83, 88, 88, + 72,176,245,247,112,229,217,173, 0,208,157,187,153,251, 29,121,192, 39, 89,158, 35, 50, 31,247,223,219, 4, 18,137,132, 15,192, + 27,128,187,161, 61,144, 0, 42, 29, 73,158,242,128, 65, 57,235, 55, 91,169,211, 71,178,124,105,245,234,213,194,115,231,206, 73, + 79,157, 58, 5, 0, 24, 61,122, 52,134, 13, 27,198, 56,149,240,163,120, 15, 47,188, 40,198,196, 9, 3,181,128,152, 39, 22,139, + 73,176,203, 62, 89,152,161, 83,167, 78,212,228,201,193,198,243,164, 36, 80,182,148, 0, 22,143,216, 3, 96,236,225,123,239,223, + 0,130,152, 89,211,146,239, 33, 28, 32,222,135, 38,207,210,239,109,225,111,126,172,127, 47, 77,252,215, 46,159,254,113,239,174, +245, 99,219,180, 15,110, 45,147,105,224,227,227,130,178,146, 60,178,119,239,254,213, 18,137,100,176, 88, 44,190,109,143, 76,241, +156,254, 84,126, 94, 14,242, 10,148, 40,186, 75,161, 99, 91, 2,193, 93, 4,232, 22, 28, 10,201,142,236,199,165,243, 91, 82, 36, +232,189, 6, 30,250, 51, 94,185,114, 69, 26, 22,118, 20,155, 55,203,145,150, 6,124,242,201, 49, 20, 21, 21, 73, 39, 79,158, 12, +129, 64,128,210,210, 82,209,212,169, 83,225, 12,133,224,149, 87, 94,161,100, 50,153, 40, 34, 34, 2,239,188,243, 78,154, 3,109, +134, 35, 22,139, 49,113,194, 64, 50, 54, 54,150, 7,108,193,239,191, 1, 18,137,132, 96,154,179,159,197,255, 14,212,234,229, 72, + 73,137, 69,100,228, 22, 76,158,188, 10, 73, 73,250,190,199, 42, 2, 15, 7,108, 34, 32,123, 24,214,132,236, 9, 2, 32,247,248, + 61,181,191,117,253,186, 53,175, 30, 58,248, 67, 92, 72, 72,247, 30,211, 94, 28,141,142,237,189,225,235,227,138,154, 90, 37, 74, +238,118,228,220,202,175, 9, 60,116,240, 7,233,250,117,107,190,125,123,209,210,117,182,228,189,251,246, 44,225,237,156, 67,210, +242,210,108,188, 20, 5, 12, 15, 7,130, 59, 3,185, 5, 20,206, 92, 80, 32, 89,154,141, 41,227,189,169,174,161,147, 68,223,173, +223,233, 40,145, 57,211,242, 39, 44,200,126, 36, 74, 64,117,117, 53,222,121, 71,142,160, 32, 32, 58, 26, 88,185,178, 1, 89, 89, + 89,208,106,181, 16, 8, 4,104,213,170,149,244,208,161, 67,152, 63,127,190,104,235,214,173,118,213,221,194,133, 11,133, 87,175, + 94, 69,235,214,173,165,251,246,237, 35,126,249,229, 23, 0,144,166,166,166,226,141, 55,222,192,246,237,219,237,253,173,124, 0, + 72, 62,114,145, 3,108, 33,245,127,239,207,241,207,130,181,254, 1, 96,250,244,253, 72, 73,209,255,141,141,205, 3,237, 17, 96, +189, 1, 15,151,248, 77,203,205,149, 0, 54, 8,208,130, 23,224,105, 38,127,137, 68,194, 59,158,178,247, 99,209,168,129, 61,166, + 69,133,162,127,239, 86, 8,240,115, 3, 1, 2,222,158,174, 8, 13,246, 71,196,232, 46, 24, 61, 98, 64,231,227, 41,123, 63,150, + 72, 36,109,108,201,188,157,115, 72, 58, 50,188, 14,123,215, 3,115,163,129, 30, 6,207,159,135, 59,208, 51, 4,248,108, 9, 48, +180,127, 29,110,231, 28,146,182,228, 21,181,212,235, 97, 67,145,120, 36, 3,146,191,191, 63, 14, 29,114, 67, 69, 5,144,152, 8, +212,212,240, 16, 18, 18,130, 73,147, 38,209,219,189, 34, 45, 45, 13,153,153,153,210,213,171, 87, 11,153,202,141,140,140, 20, 94, +187,118, 77,202,231,243,165, 53, 53, 77, 61, 89, 10,133, 2,219,183,111,135, 72, 36,178,183, 62, 73, 0,248,253, 55, 9,146,143, + 92,228,252,254,155,164, 69,191,125,222,188,121, 20,125, 52, 87,198,176, 93, 80, 14,148, 53,139, 45,155, 55, 11,183, 44, 89, 34, +188, 52,127, 62, 85, 52,113, 34,117,126,206, 28,106,195, 59,239, 8,183,108,222, 44,108,201,111,110,105,155,177, 36,131,105,217, +131,150, 71,187,254, 39, 79, 14, 70,108,108, 74,147,191, 52, 38, 79, 14,110, 18, 31,192,226,193, 32, 44, 44,172,201, 97, 73, 57, + 96, 21,128,199,129, 5, 30, 34,174, 93, 62,189, 50, 36, 36, 36,116,240,192,182, 77, 27, 2,135, 0,159,207,133,155,128, 7, 23, + 23, 14,130,187,250, 33, 56, 56,164,213,181,203,167, 15, 73, 36, 18,171,158, 34,241,156,254, 20, 23,117, 88, 50, 23, 80,170,128, +219, 69, 64,141, 12,168,173, 3,118, 30, 4, 22,125, 10,196,173, 6,134, 13, 4, 56, 84, 29,196,115,250,179, 29,223, 4,125,251, +246, 21,253,254,123, 79,180,106, 5,204,154,197, 67,155, 54,207, 98,244,232,209,162, 67,135, 14, 17,147, 38, 77, 18, 69, 70, 70, +162,117,235,214,184,120,241, 34,246,236,217, 35,157, 62,125,186,240,251,239,191,111,150,128, 70,142, 28, 41, 84,169, 84, 82, 23, + 23,151,102,191, 91, 42,149, 98,236,216,177, 76,200,140,154, 61,123, 54, 37, 22,139,213,134,152, 17,152,144, 63, 1, 0,179,103, +207,182, 91, 65,203,200,200, 48, 30,205,149, 57,216,109,137,150,116,239, 45,155, 55, 11,187,221,188, 41,157,122,233,146,180, 99, + 78, 46,248,117,117,104,155,115, 19,194, 63,206, 75,131,178,179,165, 18, 7,149,128,140,140, 12,204,155, 55,143, 90,180,104,145, +195, 74, 4, 45,131, 73, 25, 83,121,230, 68,207,164,204, 22,104,210,167,255,170, 39,135,176, 29,254, 33, 18, 63, 19, 60,169, 10, + 0,101,225,112,154,224, 7,248,124,148,147, 31,147,178,183, 46,174, 93,207,158, 16, 26,236,111, 36,125, 75,219, 52, 11, 92,121, +208,106, 73,132, 6,251,227,218,245,236, 96, 0, 62,214,228,229,231,229, 32,106,140,254,255,163,233,192, 27, 31, 2,155,119, 2, +165,247,128,155,185, 64,214, 53, 10,169,103,129, 19,231,128,200,209,250,251, 91,160,155, 17, 15,240, 21, 63, 18,197,100,217,178, +101,105, 13, 13,250,120,203, 89,179,102,225,252,249,243,132, 68, 34, 73,163,175, 85, 87, 87,139,122,246,228, 97,254,124, 96,192, +128, 11,208,233,110, 74,139,139,139,173,122, 82, 22, 46, 92, 40, 36, 8, 66,202,116,115,152,242,242,114,155, 94,153,217,179,103, + 35, 33, 33, 1, 0,168,244,244,116,181,201,187, 32,104,226, 79, 72, 72,192,236,217,179, 31,229,120,224,104,153, 69,168,174, 94, + 69,215, 63,255, 52,108,130,164,134,150, 36, 65,106,116, 32, 53, 90, 4,157, 78, 71, 29,195,253,214,173, 17,238, 95,127,253, 37, +125,238,185,231, 30,184, 18,224,136,119,161,165,228,175,158, 28, 98,241, 72,137, 77, 97,217,249, 49,131, 69,203,174,153,224, 55, +202, 65,195,153,114,162, 60,226, 49, 24, 92,154,125, 6, 27, 65,133,148, 51,234,207,145,192, 69,137, 68,194, 75, 79, 63,210,171, + 93, 27, 79, 80, 20,112,250,124, 17,228, 10,253,174,171, 3,251,183, 65, 80,128, 27,138, 74,234,201,220,219, 53, 28, 30,143,131, +238,221,252,208,174, 93,136, 47,244, 91,180, 90, 68, 94,129, 18,195,195, 1,149, 6, 56,114, 10,144,158,167,208,174, 53,129,110, +157,128,177, 35,128, 30,193, 4,120, 92,253,214,226, 67,195,128,111, 36, 74,166,245, 77,216,249, 63, 83, 37,130,194,253,177, 0, +212, 35,106, 91, 0, 64,111,231,138,126,253,250,137,204,175,113,185, 92,105,175, 94,229,136,139,211, 63,230,138, 21, 57, 40, 40, +232,109, 85,150, 82,169,180,105,249,155,162,160,160,192,230, 61, 9, 9, 9, 70, 43,159, 86, 4, 76,174,209, 10, 2, 97,184,246, + 56, 56,237,136,150,142, 27,221, 43,171,164,106,141, 6, 28, 14, 7, 20,151, 11,146, 36,161, 33, 73,144, 58, 29,116, 58, 18, 29, +238,222,149,182,164,189,200,229,114, 0,144,206,155, 55, 15, 4, 65,216, 29,223, 97, 74,248,219,182,109, 35,154, 43,123,152,228, + 15, 0, 41,177, 41,136,220, 18,137,233,251,129,216, 20,253,255, 52,249,171, 39,135,128,159,148,203, 50,239, 67,132,169,219,159, +209,118,192,214, 86, 1,180, 96,117,128,181, 40,118, 71,162,219, 41, 27,131,187,195, 74,131, 21, 82, 37, 28,177, 34,154, 9, 42, +116, 68,158,213,207,208,223, 67, 0, 32,247,218,140, 93, 32,245,209,254,174, 0,128,162,210, 58, 40, 20, 90, 0, 64, 72, 55, 63, + 4, 5,184, 33,251, 90, 57,231,239, 91,213, 16, 8,184, 8,238,234,139, 26,153, 26, 0,172, 10, 46,186, 75, 33,184,179,254,251, +159, 31, 5,132,245, 34,224,202, 7,180, 90, 96,252, 72,192,215, 11,200, 47, 4, 34, 71, 1,157, 59,232,239,127,196, 32,204,188, + 39,143, 74,177,124, 32, 40, 47, 47,183,171, 31,214,215, 51,223,125, 55, 33, 33,129, 48, 81, 2, 76,189, 3,143,188,238,186,117, +235, 70,229,231,231, 19,142, 94, 55,135, 75, 94, 46, 84, 26, 53, 8, 46, 15, 58,138, 2, 1, 64,171, 35,161,209,146,160,116, 58, + 16,183,254,118,202,115, 95,189,122, 21,129,129,129,210,175,191,254, 90,244,193, 7, 31, 56,172, 4,152, 79,163,216, 75,220,206, + 34,255,194,194, 66,162, 83,167, 78,212,244,253, 77, 21, 2, 0,136,220, 18, 9,126, 82, 46,146,146,242,140, 43, 1,216, 88,128, + 71, 71,254, 86, 21,128, 39, 0,205,145,168,221, 4,219,194, 37,142,214,229, 62,224,213, 4,196,204, 26,123,191,131,240,241,113, + 65, 77,173, 18,129,254,238,136,158,210, 3, 90, 29, 9, 87, 87, 46,184, 28, 14, 40,138,194,164,241,193,136,138, 8, 6, 65, 0, + 85, 53, 10,248,248,184, 0, 64,181, 53,129, 29,219, 18,200,187, 67,161, 71, 48, 48,230, 57,125,101,223,204, 5,250,245, 0,252, +188,129, 9, 66,128, 36, 1, 30, 23,200,185,173,191, 63,191,136, 98,250,110,237,249,191,165, 3,201, 35, 89, 6,184,105,211, 38, +225,234,213,171,145,151,151,135,244,244,116,233, 55,223,124, 35,242,244,244, 52,110, 59,171,211,233, 68,215,175,183,146,254,231, + 63, 37, 32, 8, 2,229,229,161, 8, 13,237,130,156, 28,203, 83, 41, 36, 73, 90, 44, 31, 59,118,236,253, 94, 36,138,194,201,147, + 39,237,250,205,166, 74,192,227, 68,254,206, 80, 18, 76, 81,221,161, 61,248, 55,255, 6,229, 2,240, 73, 10, 4, 1,104,116, 90, +168, 41, 29,228, 90, 45, 20, 33, 61,128,235, 55, 91,252,236,125,250,244, 1, 65, 16, 14,145, 63, 0, 12, 30, 60, 24,219,182,109, + 35,250,245,235, 71, 53, 87,102, 11,219,182,109, 35,204, 9,223, 82,153, 61,136, 77,249,135,248, 1,220,103,249,211, 1,131, 73, + 73,121, 44, 83, 63, 2,242, 7,216, 32, 64, 83, 18, 49, 63, 90,108, 21, 82, 20,192,121,169,230,129, 61, 52,181,215, 79,255, 29, +204, 21, 24, 94, 89, 73, 94,101, 81,137,222,234, 91,179,233, 47, 92,186, 90, 14,141,134, 4, 73, 82, 6,165,133, 48,198, 6, 20, +149,212,163,172, 36,239, 54, 0,171,102,101,112, 23, 1,206,102,234,255, 15, 12, 7,178,174, 1,177, 49, 64, 72,103,189,219,255, +139,245, 0,223, 5,224,112,128,179,153,250,251, 91, 64,208,206,142,161, 48,127,223, 15,221, 26,185,126,253, 58, 4, 2,125,157, + 28, 62,124, 24, 9, 9, 9,210,180, 52, 61, 23,172, 94,189, 90,232,239,239, 47,189,113, 67,139,173, 91,129,172,172, 65,224,114, +123,136, 58,116,232, 32,178, 38,207,195,195,131,241,119,107,181,218, 39,190,227,154,146,127,183,110,221, 40,107,135,189,202, 66, + 94, 80, 43, 81,141, 90,133, 58,181, 26, 10,181, 6, 42,173, 22, 26, 74, 7,185, 70,131,122,181, 26,165,237,218,137, 90,242,220, +238,238,238,240,240,240, 16,109,219,182,141,112,196,253,111, 74,244,182,202,236, 81, 2, 6, 15, 30,108,179,140,137, 23,192, 26, +249,155, 90,255, 44, 30, 45,249,179, 10,192, 67,192,131, 94, 82, 72,237,245, 3, 5,198,138,134,182,119,239,254,165,185,183,107, + 64,146, 20, 62,124,119, 40,114,114,171,113, 35,167, 10, 4,129, 38, 1,129, 36, 73, 33,247,118, 13,122,247,238,127, 21,128, 85, + 63,113,183,224, 80, 28, 62, 9,232,116, 0,149, 15, 72,207, 3, 73, 39,128, 9,175, 3,162, 89, 64,218, 31,250,251,116, 58,224, +240, 73,253,253,143, 16,150,230,255,225, 12,101,207, 81, 84, 87, 87, 75,123,246,188,141,140, 12,224,252,121, 29, 58,116,184,140, +172,172, 44,233,228,201,147,169, 67,135, 14, 73, 83, 82, 82,112,239,222, 61, 12, 28, 56, 16, 47,189,244,146,104,255,254,253,105, +205, 37,241,161, 40, 74,100,205, 11, 96, 14, 90,241,176, 23,244, 20,192, 35,154,243,111, 2, 83,139, 62, 63, 63,159,176,118, 88, +186,191, 57,248, 13, 24,128,170,145,163, 80,173, 80,162, 70,163,130, 82,171, 69,131, 70, 7,153, 90,141,250, 49, 99, 17, 24, 30, +238,160, 87,144,192,224,193,131,209,183,111, 95,209,249,243,231,211, 90, 34,195,148,232, 45,149,181, 68, 9, 48, 29, 11, 44,149, + 49,129, 37,242,167, 45,127,243, 76,129, 44, 30, 62,249,179, 10,192,147,238,182,152, 89, 99,215, 52,128, 88, 44,214,245,238, 55, +114, 76, 94, 94,238,205, 63, 51, 75, 65,146, 20, 38,140,235,134,203,215,202,241,229,154,243,248,226,219,115, 70,242,255, 51,179, + 20,121,121,185,119,122,247, 27,249,182, 88, 44,214, 88,147, 41,217,145, 77,232,224,141,248, 31,244, 36,191,249, 11,224,191,191, + 2,162,161,192,128, 94, 64,218, 46,125,121,252, 15,128, 14,222, 45,201, 8,216,210, 85, 0,148, 13, 57,143,100, 46,178,177,177, + 17,125,251, 42,241,236,179,192,179,207, 2,131, 6, 81,200,207,207, 71, 82, 82, 18,254,248, 67,175, 61, 9,133, 66,132,135,135, + 51, 74, 15,188,127,255,254, 52, 38,196,174,213,106,225,229,229,101,183, 21,107,136,250, 55, 70,252,211,231,142, 90,176,244,209, + 92,153, 61, 74,128, 51,238, 3, 0,241,194,133,105,234, 33, 67, 68, 55,198, 71,136,202,158,121, 6,101, 46, 46, 40,235,209, 3, + 57,145,145, 34,221,115, 67, 69, 98,195, 20,141,189,120,246,217,103,209, 18,171,223, 84,134,173, 50,166,117,104,201,234,127,246, +217,103,109,150, 57, 2, 58, 71,192, 63, 73,129, 88,143,192,131, 2,147,165,128,108, 38,192, 7,104,153, 63,142,223, 33, 22,139, +171,214,175, 91,179, 54,229,232,158,247,139,239,214, 7,135,116,245, 67,212,248, 96,248,249, 10,240,255,219,251,246,248, 38,170, +244,253,103,146, 52, 77, 75, 10, 45,229, 90,180,210,114, 19, 65, 46, 22,177,138,151, 70,185, 24, 74,185, 54,226, 34, 46,136,216, +202, 42,160, 22, 72,101, 23, 69, 87,191, 82, 22,148,149,245,146, 42,151,250,219, 85, 48, 45, 88, 10,212, 98,217,212, 21, 1, 23, +170,128, 92, 86, 75,139, 20, 41, 80, 40,244,146, 52,105, 50,153,243,251, 35,153, 50, 77,115,153, 73, 82, 90,116,158,207, 39,159, + 38,103,102,158,206,204,153, 57,207,251,190,231, 61,231, 92,171,181,224,135, 31, 47,225,244,153,107, 40, 47, 63,189,127,194,163, + 51,183, 1, 56,231,139, 51,110,224, 36,213, 55,165, 59, 13,251, 75,235,145,252, 48,240,209, 91,142,153, 0,203,207, 2, 27, 62, +119,120,254,118,116, 70,220,192, 73, 42,236,249, 52, 24, 2, 30,236, 99,219,109, 20,192,133, 11, 23, 84, 81, 81,221, 12,135, 15, + 95, 6, 0,252,252,115,103,220,125,247, 29,136,142,142,134, 66,161,192,133, 11, 23, 84,147, 38, 77, 18, 52, 21,112,223,190,125, + 85, 63,253,244,147,193,147,199, 70,211, 52,250,247,239,143, 13, 27, 54, 8, 18, 33,215,190,127,206,111,226, 79, 46,128, 59,111, +213, 95, 15,214,151,184, 11, 17,127,174, 17,208,226,185, 56,118, 44,224,250, 14,212, 67, 23,114,223,248,254,175, 96,243,121, 19, +127, 46,172, 41,253, 1,177,255,255,134, 68, 2, 60, 25, 6,130,134, 1, 6,144, 44, 23,236,177,215,196,207,109, 55,228,252,124, +220,167,160,156, 95, 32,137,139,207, 47,124, 73,167,211,233,182,156, 56,246,205,251,219,243,191,142,239,213,167, 95, 34,103, 45, +128,131, 67,134, 12,255,239,164,201,243,150,167,167,167,155,248,240, 57,167,247,165,210,231, 14, 39, 91,119,253,140,255,123,207, +195, 90, 0,254,139,127, 80, 2, 38, 29, 77,252, 1,224,241,199, 31,199,209,163, 71,241,212, 83,135, 1, 0,163, 70,141,194, 99, +143, 13, 87,189,248,226,139,205,226,252,237,183,223, 10,226,252,224,131, 15, 74, 0, 80,201,201,201, 73, 13, 13, 13, 6,169, 84, + 10,137, 68, 2,154,166, 33,151,203,161, 84, 42, 85,129,138, 63,128,160, 24, 1, 34,126,155,168,172,172,164,138,210,138, 72,204, +194, 24, 21,250,186,223,167, 42,173,200, 32,122,255,237, 11,153,128,134, 50,216, 13,111, 91,240, 81, 29,252,252, 58, 2, 31, 27, + 9,168,211,233,116,179,135, 12,123,128,157, 49, 70, 9,160, 27,128, 11, 0,204,206, 85,222, 4,193, 53,188, 95,113,142,160,226, +156, 25,248,230,104,123,223,135,142, 52,175, 68, 11, 56,133,190,249, 28,142, 31, 63, 30, 52,238, 93,187,118,149, 4,235,250, 56, +253,254,148, 75, 57, 5,231, 68, 64, 34, 68,184, 26, 1,149, 75, 43,209, 81,223,189,223, 42,248,206, 2, 8, 0,148,191,235, 8, +139, 16, 33, 66,132, 8, 17, 34,110, 94,136, 73,128, 34, 68,136, 16, 33, 66,132,104, 0,136, 16, 33, 66,132, 8, 17, 34, 68, 3, + 64,132, 8, 17, 34, 68,136, 16, 33, 26, 0, 34, 68,136, 16, 33, 66,132,136,223, 6, 90,140, 2, 56,114,228,136,223, 89,153,238, +146, 9, 69,190, 54,227,243,185,136, 77,123,242,105, 52,154, 36, 0, 6,189, 94, 31, 20,190,153, 51,103, 38, 49, 12, 19, 52, 62, +241,249,115,203, 87, 5,160,119, 91,158,223,130, 5, 11,102,166,167,167,127,222,150,215,171,211,233, 66, 0, 40,156,207,180, 5, + 0, 3,128,164,167,167, 19,241,121, 17,249,126, 79,124,193,138, 0, 16, 30, 31, 33, 8, 54,223, 13, 3,185,186,154, 16,227, 58, +222,231,231, 20,194,160, 93, 47,135, 15,107,215,174, 85,121,185,159,130,249,142,191,215, 25,129,242,177,152,122,247,110, 67, 92, +231, 2, 0, 64, 66, 66, 66,192,245, 57,176,231, 86,220,214,125, 47,194,194,194, 48,118,236,216,142,244,124,116,167, 58, 41,191, + 4,208, 61, 0,142, 8, 56,134, 96,118, 1, 16, 43, 9, 13, 47,242,194, 23, 2,223, 67,167,216,181,128,187, 43, 20,225,236,185, + 73,121, 28,119,193,207,247, 88, 8, 14,180, 85, 69,100,103,103, 79,252,248,227,143,151,132,132,132,108,151,203,229,165,114,185, +252,127, 0,116, 82,169, 84, 79, 81,212,251, 58,157,174,155, 78,167, 19,135,157,137, 16,225, 41, 2,224,238, 37, 39,196,243, 59, + 46,112,110,104,226, 36, 12, 22,159, 32, 15, 54,152, 72, 77, 77, 37,167, 79,159,246, 41,174,122,189,222,160,213,106,209,163, 71, + 15,183, 83,174,102,100,100, 24,132,136,181, 94,175, 55,172, 93,187, 86,149,145,145, 97, 56,120,240,160,193,197, 16,240,139,143, + 57,249, 10, 36,119,188,142, 79,254,109, 5, 0, 48, 39, 95,185,110, 29,222,241,186,160,251,242,217,223, 58, 17,134, 0, 91,190, +116,112,169, 31, 10,193,144,254, 39, 0, 56,140,128,210,210, 82, 65,117,179,250, 61, 85, 82,237, 47, 53, 48, 90,163, 12,166,166, + 78, 80, 79,168, 69,159, 94, 20,226,226,230,144,250,122, 11,182,110,221,218,174, 13,186, 68,161, 88, 68,108,214,241, 18,133, 98, + 17, 99,177,172,240,147, 70,201,138,175, 68,174, 88, 66,236,244, 56,137, 92,177,136,177,186,229,179,241,224,179, 17, 66,168,208, +208,176, 69, 52,109, 27, 47,151, 43, 22, 89,221,112, 17, 66, 36, 20, 69, 49, 55,248,150, 89,185,207, 95,110,110,174, 97,250,244, +233,170,188,188,188,146, 64, 72, 63,254,248, 99,181, 76, 38,123, 80, 38,147, 61, 46,149, 74,163, 36, 18,137, 50, 43, 43, 75,178, +116,233,210,121,118,187, 29,180, 3,143,219,237,246, 20,157, 78,247,173, 51, 26, 96,117,182,127,109,222, 13, 58,121,242,100,194, +183,189,203,207,207, 23,244, 76, 79,153, 50,133, 4,114,188,136,223, 62,216, 25, 1,133, 46, 7,236, 83,252, 19, 18, 18, 80, 90, + 90, 42, 68,156,189,138, 60, 79,190, 86,252, 90,173, 22, 21, 21, 21,112,134,136,131,182,172, 43,169, 74, 32, 8, 27, 8, 42,234, + 51, 10, 0,168,174,203,168,212,212, 84,159, 94, 15, 87,172,171,171,171, 13,158,196, 95,171,213, 34, 43, 43, 75,144,248, 59,127, + 35, 49, 49, 81,149,152,152, 24, 16, 31, 43,246,236,223, 85,127, 69, 11,241, 95, 54, 67,129,213,121, 22, 94,247,106,203, 58, 37, + 25, 26, 39,129,201, 76,240,210,147, 10, 28, 60, 65,195,108, 34,104,180, 2,170, 17, 39,112,226,103, 59, 18, 18, 18, 8, 95, 35, + 64,251,151,219, 73,249, 15,245,136,232, 44, 71,175,222, 74,116,239,217, 31,103,203,173,232,123,135, 13, 33,138,106, 20,111,191, +130, 71, 31,125,148,124,249,229,151,237,213,224,133,118,141,142, 94,252,207,131,255,165,212,131, 6, 44, 2,240, 6,128,166, 64, +248,162,187, 70, 47,222,242,239,131,212,184, 17,131, 2,226,163, 40, 74,222,171, 87,239,197,123, 12,223, 80,163,134, 15,113,203, +213, 14,226, 15, 0,205,203, 15,234,245,122, 67, 74, 74, 10,242,242,242, 12,238,222,215, 67,135, 14,145,215, 94,123, 13, 59,119, +238,244, 90,191, 27, 54,108,120, 88, 46,151, 15,149,203,229, 11,229,114,121,248,185,115,231, 48, 96,192, 0, 72,165, 82, 68, 68, + 68,224,244,233,211, 80, 42,149,178, 67,135, 14, 69, 30, 56,112,224,155,231,158,123,174, 47,128,179, 0,228,112,116, 15,120,108, +248,184,237, 31,183,221, 98,203, 41,138, 2,197,195,107,217,177, 99,135, 71, 14,110,185,183,246,214, 19,242,243,243, 3, 58,190, + 45,177, 96,193,130, 36,231,172,148, 34,218, 73,244,253,141, 0,240, 18,127,190,208,106,181, 62,247,225, 35, 92,158,196,127,213, +170, 85,200,204,204,116, 53, 58,252, 18, 6,114, 56,129, 32,122, 32,168,184,207, 40,174,199,159,155,155, 75, 1, 0,251,215, 83, +159,139,171, 88,123, 19,127,103,100,192,167,215,174,215,235, 13,174, 30, 62, 91,198,189,199, 66,249,188,121,248,203,102,240, 95, + 41, 46,111, 93, 39, 50,224, 54, 9,194, 66, 41,220, 22, 35,197,149,107, 12,108,180, 20, 53,181, 4,117, 70,130,211,191, 50,128, + 4,232, 22,126,140,189, 63, 94, 27,133,229,127, 30,148, 52,176, 95, 60, 14, 92,188,132,184,216,238, 24, 58, 44, 30,210,208,174, +184, 45,238, 26,174,153, 45,168,190,104,199,175,151, 44, 8,151, 85,240,226,107, 35, 60,241,228,210,165,242,138,222, 49, 8, 77, + 24, 37,177,124,243,159, 39, 0,108,244,131,231, 18,203, 55,103,209, 18,249,175,242, 94, 80, 14,188, 75, 82,127,124,159,191,124, + 0,240,196,115,139, 95,148, 35, 52, 2,113,131,134, 72,126,250,241,251, 64,184,130, 86,165,131,118, 0, 0, 30,239, 73, 68, 65, + 84, 9,134,227,253, 67,161, 80,168, 0, 24, 92,235,240,240,225,195,188,196, 31, 0, 66, 66, 66, 34, 21, 10,197,220, 43, 87,174, +132, 15, 28, 56, 16, 35, 71,142,132, 76, 38,195,187,239,190, 11,187,221,142, 59,239,188, 19,219,182,109,195,161, 67,135,112,236, +216, 49, 72,165,210,247,117, 58,221,148, 15, 62,248,192,155, 87,221,220,206, 5, 35, 98,169,211,233, 84,189,122,245, 50, 16, 66, +188, 30,115,241,226, 69, 85,122,122,186,160, 27,202,114,251,123, 60, 43,212,167, 78,157,242,218,110, 12, 30, 60, 88, 37, 84,204, + 79,157, 58,101,152, 53,107, 22,186,116,233,162, 18, 13,129,142, 9,153, 39,143,221,151,167,222, 81, 80, 81, 81,129,204,204, 76, +127, 13, 8,143, 72, 77, 77, 37, 84, 76, 46,149,154, 26, 71,244,217,163,129,205,247, 19, 74,249,130,207, 55,222,157, 88,187,138, +178,183,110, 1, 79,224, 26, 20, 7, 15, 30, 52, 36, 38, 38,182, 8,253, 11,229,251,116,169,210, 99,227,246,196, 26, 19,111,158, + 15, 62,248, 32, 41, 84,186, 20, 18, 9, 16, 30, 6,212,214, 51,104, 34, 4,157,194, 40, 88, 24,192,220, 68,112, 75,119, 9, 24, + 26, 40, 59,103, 71, 69, 69,133,193,155,113,182,120,209,184,164,184,219,194, 13,114, 57,193, 51,115,239,129,221, 78,112,177,218, +138,202,243,181, 64,200, 57,132, 69, 53,225, 66,245, 47,144,200,235,112,242,100, 45,186, 68,121,231,107, 59,247,191,235, 43,143, +255,241,143,161,127, 97,128,168,204, 63, 43, 47, 29, 61,178,130,169,175,247, 71,100, 9, 0, 40,186,116,125,229, 15,179,255, 24, +186,230,140, 29,183,204,212, 42,127,170, 56,182,194,222,216,138,143, 2,143,126,247,206, 93, 34, 95,121, 98,246,147,161,199, 42, +175, 97,242,172, 52,229, 63,254,154,177,194,220,104,242,117,110,189,133, 68,242,188,148,123,171, 11, 59,251,142, 76,154, 52, 9, +172,232,155,205,230,230, 58,100, 61,255,130,130, 2, 94,117, 26, 26, 26,122,159,201,100,186,125,240,224,193, 80,169, 84,200,200, +200,192,211, 79, 63, 13, 0,176,217,108,216,188,121, 51, 74, 75, 75,241,253,247,223, 99,235,214,173, 48,155,205,253, 25,134, 81, +251,240,216,131,250, 60,237,218,181,139, 87,215, 28, 69, 81,130,159,101, 46,183, 63,199, 59,223,225,146, 89,179,102,161,170,170, +202,237,246,152,152, 24,248, 43,224, 85, 85, 85,168,170,170, 18, 13,129, 27, 12,110,184,223, 91, 52, 64, 38,212, 99, 15,182,208, + 6, 10,103,216,223,111,144, 4, 16,244, 6,168,157,142, 23,135, 26, 85, 74,165,166,198, 53, 55,106,185,185,185, 20,178, 71, 19, +215, 72, 0, 95,177,174,174,174,110, 33,206,254,136, 53, 95,112,140, 14,159, 34,193, 39, 92,200, 9,255,187,221,249,195, 15, 63, + 36,151, 79,188,136,222, 3,165, 48,153,175,239, 98,182, 19, 88,172,128,205, 89,102,163, 9,136,196,241,253,199, 99,165,208,104, + 52, 73,101,101,101,110,255,103, 68, 68,157,193,100,150,160, 91,215, 72,212, 94,109, 68,109, 93, 45, 14, 30,190,136,243,151, 8, +228,157, 26,209,167,191, 17,230,198, 43, 24, 48,204,134,190,131,155,176,245,163, 82, 76,155, 54, 45,233,204,153, 51, 55,234,145, +147, 0, 24, 59,105, 70,106,207,170, 46, 81, 40,167,129,176,177,227, 33,137,138,238,198,212,215,143, 7,176,135, 35,132, 33,224, +244,123,123,106,247, 1,140, 75,153, 54,163,231,101, 73, 23,156, 53,218, 16,121,215, 88,200, 34,162,186,217, 27, 91,240,241,170, + 87, 0, 19,166, 78,155,222,147, 72, 67, 81,103,106,194,208,132,123,161,236,220,165,155,185,209,228,202, 37,212, 0, 8, 10, 88, +239,159,162, 40, 76,154, 52,137, 0,192,206,157, 59,161,209,104,146,180, 90,173, 65,136,248,235,116,186,208,218,218,218, 57, 54, +155, 77, 18, 30, 30,142, 7, 31,124, 16,107,214,172, 65, 72, 72, 8,210,211,211,145,147,147,131,210,210, 82, 28, 60,120, 16,123, +247,238,197,143, 63,254,136,110,221,186,117,163,105,250, 54,120, 8,255,115, 67,160,190,186, 0, 36, 18, 9,175,243,108,203, 46, +128, 29, 59,118, 4,165, 11,160, 75,151, 46,170,170,170, 42,131,167,109,129,214,187,104, 8,220, 60, 17,128,155, 9,158, 60, 34, +193, 86,112,106,106, 42,209,103,158, 1,164,114, 32, 50, 4,136,236, 11, 42,215, 73,198,179,239,191, 13, 64,184, 94, 63, 0,112, + 61,127, 55,141, 43, 18, 19, 19, 85, 94,146, 1, 5, 95,195,191,150,116,242, 24, 17,136,168,207,192, 47, 86,130,139, 87, 24, 0, + 18, 40,195, 29, 33, 78, 27, 77, 96,105, 2, 44, 86,192,210, 4, 88,109,128,197, 12, 88,155,174, 71, 73,220, 37,164,252,235,189, + 78,164,248, 96, 3,110,141, 83,130,132,200,112,197,108,134,225,235,115, 56,121,250, 60,174, 94, 53, 98, 72,130, 29, 38, 11, 13, + 75,147, 29,230, 70, 6, 23, 43, 1,179, 9,216,190,125,187, 65,200, 2, 24, 1,130,145, 70, 70,190,242,212,203, 47, 43,182,114, + 36, 36,234,229, 63, 43,175,102, 46, 89, 97,175,173,221,195,185,215, 86, 62,117, 44, 83, 70,190,242,244,139,153,138,194,243,246, +230,194, 91, 30,207, 84,158,221,240,242, 10,218, 88,187, 71, 72, 20, 32, 92, 25,177, 98,209, 75, 75, 20,229, 85,215, 87,139, 76, +153,149,166,220,146,189,118, 69,163,177, 97, 79,128,239,154,187,103, 73,200,187, 70, 88,239, 95,161, 80,168,244,122,125, 9, 59, +100,212,108, 54, 27, 70,141, 26, 37,132,139, 6,208, 31, 0, 51, 98,196, 8, 70,161, 80, 72,114,114,114, 48,111,222, 60,188,245, +214, 91, 32,132,224,187,239,190,195,215, 95,127,141, 99,199,142,161,174,174, 14, 3, 6, 12, 64,125,125,125,184, 68, 34,233,225, +139,124,234,212,169, 30, 5,213, 87,215,128, 27, 67,165, 67,119, 1,120,139, 2, 4,226,253,139,134,128,104, 0,180,137, 40,106, + 52, 26, 21,167,207,208,181, 65,164,184,222,134, 51, 36,239, 87, 72,143, 21,253,220,220, 92, 74,159, 61, 26,144,203, 65,229,230, +222,208,139,101,179,254,245,122, 61,165,209,104,136,175,104,136,107,110,128, 16, 65,119, 7,111,251,206,121,217,132,152,158, 18, +204, 74,145,195,210, 4,116,137,160, 32,161,156, 94, 63, 8, 44,141,128,201, 74, 96, 50, 19,152, 44, 4, 12, 1, 36, 94,114,174, +231, 44, 54,225,206,225, 21,232,117,251, 85,124, 85, 88,141,171, 87, 45, 24,113,111, 61,134,117, 53, 2, 33, 77,176, 52, 50,168, + 62, 79, 96, 50, 81,160,105, 10, 93,187, 81,192,141,207,101, 27, 50,114,248,240, 81, 81,177,177,216,127, 93,175,161,156, 53, 27, + 87,181, 25, 9, 0,238, 0,112, 82, 0,223,224,145,195,135,143,138,142,137,197,225,255, 54,231,200,161,187,234, 15, 56,251, 81, +166, 59,190, 48, 0,141, 30,184,238, 24, 57,124,196,168,152,152, 91,112,242,251,235, 17,145, 49,143, 36,227, 51,221, 26,127,206, +173,205, 12, 90,246,253,117,205,223, 72, 73, 73,105,149,127,228, 38, 23,128,173,244,254, 0,142, 44, 91,182,236, 62,153, 76,166, +252,228,147, 79,176,105,211, 38, 60,245,212, 83, 88,181,106, 21, 40,138,194, 47,191,252, 2,179,217, 12,173, 86, 11,154,166,241, +236,179,207, 50, 20, 69,249,124, 1,130,153, 77,223,209,187, 0,188, 69, 1,130,225,253,139, 16, 13,128,160,194, 77, 63, 50,229, +101, 63,254, 46,206, 40, 71,134,122,106,106, 31, 2,148, 65,255,238, 25, 32,108, 96,115, 36,128, 53, 10,248,116, 3, 4, 11,172, + 55,175,209,104, 8,215,251,103, 35, 2,220,223, 26,141, 6,156,201,114,136, 80, 65,119, 5,103, 20,128, 91, 62,218, 14,152, 26, + 9,154,172,142,100,191, 38, 43,129, 44,244,250, 54, 75, 35, 96,182, 17,212, 92, 37,184,124,141,224,251,147, 52, 24, 6,208,104, + 52,170,178,178,178, 86,117, 67,211, 64,213, 57, 43,206,149, 95,195,190, 3,215, 64, 8,133,147,255, 99, 48,105, 22, 13,185,140, +224,242, 37, 96,223, 30,160,190,158,128, 48,192,253, 15, 83, 80, 40, 0,181,122, 10,206,158, 61,203,235,154,212,247,130, 20, 30, +240,191,145,148, 40, 59,191,252,204,170,172,144,124, 34,105,113, 67,186,133,134, 34,228,249,197, 33,191,172, 95,183,220, 90, 95, + 63,155, 47,159, 52, 76,185,124,193,138, 85, 33,123,170, 72, 11,190,232, 78,161, 24, 58,243,185,144,147,159,191,187,220,106, 50, +114,249,204,158,184, 20, 97,157,150,103,190,178, 50,228,204,197,186, 22, 92,157, 35, 58, 97,218,172,167, 66,242, 63,221,184,220, +100, 50,205,110,231,215,151,218,185,115,103,171,178, 87, 95,125,149,236,220,185, 19, 5, 5, 5,188,171, 2,192,113, 0, 71,214, +174, 93, 59, 60, 50, 50, 82, 9, 56,194,224, 27, 55,110,196,188,121,243,176,105,211,166,102, 79,125,237,218,181,168,173,173, 69, +125,125,189,177,177,177,177,194, 25, 65,144,123, 13,245, 48, 76,139,124, 40,214,131, 39,132,240, 14,255, 3, 55, 71, 23,128,187, + 40, 64,176,189,127,150, 83,244,252, 69, 3, 32, 32,148,150,150,250,204,254,118,110,231, 71, 24,218, 9,250,190,255, 1,222,139, + 35,136,235, 4,244,107, 2, 53,168,128,194,187, 9,205,125,255,129,116, 3,184, 14, 5,244, 52, 52,208, 93, 99,201,182, 23,172, +248,187, 38, 0, 58,189,168,230, 50, 31, 17, 0,202,213, 19, 11,180, 49,191,255,161,201, 73,231, 47, 20, 26,152,238, 12, 36, 50, + 32,196,217, 46,218, 24, 2,154, 6, 26, 26, 8,172, 54,128,182, 57,140,130, 41, 83, 29,209, 27, 15, 33,123, 42,241,222,201, 73, + 77, 87,118, 27,134, 12, 97,240,205,215,118, 80, 18,224,242, 69, 10,138, 48,224,235, 47, 1,171,153, 2, 69,128, 97,119,133,160, +170,146,193, 67, 15, 37, 35, 63, 63,159,215,178,214,234,123, 65, 86, 63,231,184,126,127,141, 0,194,216, 39,216,163,187, 73, 10, +153,235, 42,212, 19, 64, 47, 10, 48, 39, 36,200,206,208,246, 9,130,248, 8, 51, 1, 17, 93, 37,134,139,246,102,190,238, 10,160, +155,130, 66,248,157, 9,178, 19, 91,152, 9,158,188,104,119, 92,157, 34, 34, 37,103, 47,213, 58,133, 5,136, 8, 11, 69, 68,184, + 28,119,141, 24, 41,219,254, 79, 50,161,157, 95, 93,183,247,156,205,250,231,238,195, 70,239,102,204,152,161,202,203,203,243,196, +103, 4,112,230,135, 31,126, 48, 62,240,192, 3,221,193, 25,211,191,113,227,198,102, 65,180,217,108,176,219,237, 40, 43, 43, 67, +247,238,221,175, 48, 12,195,203, 90,156, 58,117,170, 39, 79, 93,208, 69,223, 12, 93, 0,238,162, 0,193,244,254, 69,225,255, 13, + 26, 0,206, 49,251, 55, 52, 3,155,245,114,245,122, 61,235,241, 82,110,246, 33,172,248,115,188, 98, 65,224,142, 2, 96,203,132, +122,254,174, 9,128, 78, 52,151,101,100,100, 24,156,221, 25,188,248,184,226,239, 46, 39, 64, 40,159, 47,172,206,179,192, 23, 95, +126,126,126, 73,116, 36,133, 71, 18, 67,192, 0,176, 89, 25,132,202, 29,183,169,193, 68,208,100, 35,160,237, 64,233,113, 59,236, + 12,129,175, 33,123,249,249,249, 37, 61,187, 83,120, 40, 73,138,105, 79, 72, 97,108, 32,104,168, 3, 76, 13, 20,226, 6, 16,216, +109, 20,100, 18, 5,106,175, 50,168,250,213,138,178,255,241, 75, 24, 83,223, 11,178,110, 49, 48, 48, 22, 88,255, 18,176,240,109, +255,140, 0,210,104,154,254,124,194,200,221,189,242,119, 43,163,198,220,143,158, 0,122, 82,128,125,255, 62, 20,207,153,109,180, + 53,154,166, 9,225, 99, 44,141,211,158, 25, 59,170,112,240,107, 95, 40,123, 12,187, 15,221, 66, 41,116, 87, 80, 48,159,250, 22, + 59,254, 50,215,104, 51, 55,242,230,107,178,152,167, 77,124,228,129,194,140, 55,223, 87,222, 49, 60, 1, 17,225,114, 68,132,133, +162,252,228, 17,188,162, 93,100, 52, 11,224,242, 87,204,125, 93,174, 59,241, 95,185,114,101,171, 48,127,110,110, 46, 59, 79, 64, +137, 7,239, 31,112,228, 88, 28, 25, 52,104, 80,185,197, 98,233, 35,149, 74, 21,225,225,225, 0,128,188,188, 60,204,152, 49, 3, +102,179, 25, 22,139, 5, 77, 77, 77, 80, 42,149, 22,187,221,158, 79, 8,185,200,211,187, 14, 74,219,118,179,116, 1,112,163, 0, +236,119, 81,248, 69, 3,224,134,137, 63, 31, 78,167,224, 19,231,119, 0, 32,220, 97,137,165,165,165, 45, 4,223,157,129,208, 10, + 82, 10,144, 75,128, 48, 41,160,148, 1, 77, 13,208,191, 21, 2,172,123,154, 32,172, 43, 16,214, 85,112,223,191, 7,241,135, 27, +177,230,245, 98,184,138,191,107, 78,128, 80, 62, 1,226,239,147,175,166,150, 80,187, 74,108, 68,161, 0, 24, 6,184,115,144,244, +122,125,252,104,135,205, 78, 96,103,164,152, 62,125, 58, 47,227,228,210,101, 66, 21,126,105, 39, 52, 13, 88,109, 4,118, 26,144, + 80, 64, 82, 50,208, 80, 75,225,127, 71,205, 48, 91, 36,152,156, 50, 29,219,182,109,227, 37,254, 43,159, 6,250,223,226,248,221, +175, 15, 16, 64, 36,224, 32,211,208,160,190, 56,101, 98, 97,236,142,221,202,216, 49,247,195,182,127, 31,182,165, 76, 52, 90, 27, + 26,212, 0,246, 9,228,219,103, 55, 55,168, 79,189, 58,181, 48,230,111,249,202, 62,119,143,129,233,212,126,252,235,249, 41,198, +166, 70,193,124,251, 44,230, 70,245,218, 63,255,169,240,175,127,223,160, 76,188,247, 62,156, 62,113, 4,139,210,102, 27, 27,141, + 70,127,206,173, 77,225,101,178, 31,146,156,156,204,103, 52,128, 52, 50, 50,242,136,217,108,254,103, 69, 69, 69,223,225,195,135, +199,211, 52, 45, 11, 9, 9, 65,126,126, 62,198,141, 27, 7,139,197,130,198,198, 70,148,149,149,213, 71, 69, 69,253,219,108, 54, +127,194, 48,140, 9, 60,103, 0,228, 38, 36, 8, 13,253,115, 12,137, 86,145,131,142,216, 5,192,141, 2, 4,131,199,159,185, 3, + 68,220, 4, 6, 64,123,120,254,110,188, 15,226,114, 62,193,242, 82, 60, 70, 4,248, 70, 0,130, 45,254,172,177,227, 18,222, 39, +220, 50,161,124,190,114, 1,132,242,153, 44,132, 50, 89, 64, 36, 18, 96, 95,169,163,175,159, 77,248,115,244,251, 79, 23,196,215, +208, 64, 40,202,217,205, 78, 73, 28, 28,255,253, 15, 96, 50, 50, 32, 12, 48,121,114, 50,182,109,219,230,179, 62,212,247,130,104, +103, 3,145, 74,160,234, 10, 16, 22, 10, 48, 4,232,164, 0,222, 76,247,219, 8,216,199, 52, 52,168, 75, 39, 79, 44,236,178,242, +117,101,201,202, 87,140, 77,254,137,127, 11, 35,160,100,217,148,194,176,231, 95, 85, 22,253,227, 53,127,196,191,153,139,182, 89, + 39,190,242,194, 51,187, 23,102,104,149,239,191,147,101,108, 52, 26,213,132,144,163, 46, 2, 36,163, 40,138, 22, 26, 0, 9,102, + 84,192,157,248, 83, 20, 69,146,147,147, 1, 0,147, 38, 77, 34, 20, 69,121, 51, 4,148, 86,171,213, 40,145, 72,138, 99, 98, 98, +110,105,104,104,120,238,240,225,195,189, 71,142, 28,201,208, 52,221, 88, 87, 87,119,233,232,209,163,191,196,197,197,149, 71, 71, + 71, 87,152,205,230, 60,154,166, 47,165,165,165,153, 70,140, 24,193,203, 0, 96, 39, 5, 10, 4, 58,157,142,183,160,250,211, 5, + 16,200,241,158,162, 0,193,104, 51, 69,241,191, 73, 13, 0, 30, 99,253, 5,189,232, 2,230, 14, 16,194, 75,113,178,252,253, 22, + 47,170, 20, 84,106,220,163, 4, 63, 3,248,217,117,107,157,243, 35,108,140,185,243,122, 13,193, 18, 87,151,251, 66,216,121, 6, +156, 9,130, 20, 39, 26,226, 23,223,191,150,116,226, 26, 5,254,240, 53,243,206,152,113,189, 78,216,132, 63,189, 94, 95,226, 15, + 31, 97, 90,214,177,177, 30, 72, 78, 78,198,174, 93,187, 40,214,171,226, 85, 31,255, 12,234, 59,211, 5,192, 21, 0,251,108, 13, + 13,234,175, 87,190,154,211,212,208, 48,199, 41,214,131, 0,252,228,175, 17, 96,109,108, 80,239,121,255,181, 28, 75, 99,195, 92, + 0,251,225, 88, 39,192, 40,148,136,166,233,111,104,218,168,126,127,221,234, 28,163,209, 56, 7,192, 62,215,190,103, 63,196, 63, + 24,144,114,127,184,138, 63,155,183,195, 77, 18, 76, 73, 73,241,198, 87,105,181, 90, 67, 9, 33, 13, 12,195,232,172, 86,235,119, +177,177,177,221,106,107,107,169, 21, 43, 86,212,215,213,213,213,244,233,211,167,193,104, 52,154,172, 86,107,189,205,102,107,154, + 63,127,190, 89,160,135, 29,176, 19,145,158,158,222,102, 66,216,150,220, 34,126,159, 6, 64,176, 61,251, 54,139, 20, 56, 69,148, +114,231, 45, 11, 65,144,179,250,249,204, 22, 24,208, 63, 16,178,232, 79, 48,162, 1,126,212,137,199,223,129,242,237,218,181, 75, + 80, 93, 5,146,241,239, 1, 87,184,162,109,105,168,239,199,249,253, 83,128,220,251,204,198, 6, 46,159, 49, 16, 46, 99, 67, 11, +174,142,240, 46, 83, 0,144,157,157, 77, 36, 18, 9,216, 15, 55,132,173, 86,171,193, 48, 12, 24,134, 65, 90, 90, 26,229, 99, 84, + 0, 69,211,116, 56, 33,196,206, 48, 76,147,205,102,251,143, 84, 42,165, 36, 18, 73, 40,128, 80,134, 97, 96,183,219,165, 52, 77, +203,105,154,238, 61,127,254,252, 83,156, 99,219,124, 17, 32, 17, 34, 58, 2,188,205,145, 66,249,187,142,176, 8, 17, 34, 68,116, + 0, 52,114, 4,157,225, 56, 54, 50, 78,249, 5, 56, 34, 55, 10, 81,248, 69,136,240, 30, 1, 16, 33, 66,132,136,155, 5, 10,167, + 17,192,112,132, 95,130,235, 43, 15,202,112,125,154, 99, 70,188, 93, 34, 68,136, 6,128, 8, 17, 34,126, 27,144,192,145, 43,193, +130, 21,126, 57, 71,244, 25,231,126,162,247, 47, 66,132,104, 0,136, 16, 33,226,119,210,166,137,162, 47, 66,132, 23,235, 89,132, + 8, 17, 34, 68,136, 16,241,123,182,150,143, 28, 57,194, 93, 72,135,184, 76,162, 67,208,114,161,157, 74,189, 94, 31,203,254,118, +151, 76,200,229, 19,138,223, 34,159,155, 97,139,148,120,255,196,250,184, 89,248, 98, 99, 99,155,247,169,172,172,164,132,242, 45, + 88,176, 0,233,233,233,148,248,252,249,199, 41,190,191, 34,159, 16, 62,193, 6,128, 64,116,231,185, 31,209,104, 52,130,103,150, +242,180, 94, 60, 90, 79, 70,226,110, 53, 64,119,251,220,112,176, 2,227, 28, 11,111,208,235,245,205,179,117, 9,157, 79,188,173, +144,146,146,146, 84, 80, 80,208, 44,130,201,201,201,170, 93,187,118,149,252, 22,173, 93,119,245,113,234,148, 99,100,216,224,193, +131,219,251,244,200,148,169,233,200,255, 66,231,246,153,157, 50, 53,157, 56,183,121,124,112,166, 76, 77,247,218, 8,228,127,161, +243,251,161,139,141,141, 37, 41, 41,215, 71, 21, 22, 20,128,248, 50, 2,124, 97,205,218, 53, 73, 59,246,236, 64,252,144,120, 3, + 40,224,212, 15, 39, 85,247,142,184, 15,235,222, 94, 39,232,249,155, 51,103, 78,171,235,206,201,201,161, 32, 66,132,136, 54, 51, + 0,228,124,119, 76, 76, 76, 20, 76,238,197, 0,112, 43,162,174, 11,109, 8, 16, 90,127, 44, 39, 62,141, 11,209,235,245,208,106, +181,200,202,202, 50,120,153,166,147,207,255,111,177, 79,159,184, 91, 1, 0,151, 44, 22,208,230, 38, 71, 97,109, 61, 43,114,252, +166, 63,110,110,200, 11, 90,204, 41,224,156, 91, 92,208, 26,239, 18,202, 49,187, 30,251, 23,240,249,189, 61, 26,231, 22,245,193, + 10,127, 0,245, 17,204,107, 32, 83,166,166, 99,162,250, 46, 11,144,174,112, 10,189, 95,255,131, 99, 64, 4, 29, 86,171, 22, 69, + 69,105,152, 48, 33, 27, 41, 41, 89, 40, 40,112,220, 43,127, 12,129, 39, 23, 61, 73,106,187, 94,197, 59,186, 53,136, 10,143, 2, + 67,219, 97, 33, 77,134, 47,191,219, 51, 97,166,253, 49,114, 95,252, 24,213,226,197,139,125, 26, 2,115,230,204, 33, 11, 22, 44, +112,123, 79, 69, 35, 64,196,239, 25, 71,142, 28,113,141, 18,180,218, 39,144, 28, 0, 65,199,186, 46, 95, 27, 44,124,168,211, 37, + 5,220,250, 18,194,251,195,151, 82,171,213,130, 16,130, 85,171, 86,121, 59,142, 8,158,191, 59,178, 51,142, 85,108, 65, 89,197, + 62, 92,171,250, 59,202,255,150,134,109,207,206,104,215, 7,237,216,143,199,155, 69,254,248,113,199,119,224,250,119,110, 57, 67, +120,215, 9, 47, 8,169,143, 83,167, 78, 97,238,220,185,240, 42,254, 60, 12,198, 71, 30, 41,244,215,112,244,136,137,234,187, 26, +211,210,210, 20, 19,213,119,249, 45,236, 78, 15,223,219,199,111,239, 31, 0,102,204,112,172,202, 55, 99, 70, 30, 10, 10,202,145, +146,210, 15, 41, 41,253, 90,116, 13,248,124, 95, 63,252, 48,105,230,139,143,145,103,158,159,135,229, 83,151,225,174,216,187,209, +183,115, 95,244,141,234,139, 33, 61,238,196,243, 99,255, 84,244,242, 75,153, 56, 80,189,223,240,206, 59,239,240,122,183,175, 92, +185,210,226,115,207, 96, 51, 54, 47,254, 22, 51,103,206, 36,220, 79, 32,245,163, 86,171,131, 90,223,193,230,107, 75, 44, 88,176, + 32, 41, 24, 28, 65,224,137, 6,144, 0,224,101, 0,235, 0, 20, 1,200, 2,240, 87,231,231,118, 81,246,221,139,191,167,178, 22, + 17, 0,173, 86, 75, 42, 42, 42, 0, 0,241,241,241,224, 46, 54,163,215,235, 91,252,118,221,238,205, 99,175,174,174, 54,232,245, +122,222,145, 0, 95,198, 2,215,171,127,214, 57, 21,166,155,169, 78, 5,221,176,236,236,108,159,251, 20, 23, 23,243, 18, 27,141, + 70,131, 85,171, 86,185,221,152,153,153,137,172,172, 44,104,181, 90,143,251,184, 67,159,184, 91,113,254, 90, 29,182, 61, 59, 3, +209,212, 24,148,127,180, 4,241,211,226,241, 85,121, 13,166,175,218,212,174, 15,219,176, 59,135, 54,127, 31, 58,116,104,139,114, + 54, 50,192, 45, 15,182,103,239, 67,220,136, 70,163,193,220,185,115,221,110,220,188,121, 51,178,178,178,160, 30, 51, 18,133,223, +254, 0, 68,116, 2,234,141, 55,252, 30,238, 46,252, 62, 28,200,198,238,194,239,131,194,119,233,111,209, 94, 5,166,231,210, 26, + 94, 47, 8, 55,244,159,150, 86,132,148,148,126,205,127, 89,164,164,244,227,221, 37,240,209,103, 31,225,173,247,222,192, 3, 3, +146, 96,111,106, 2,109,167, 65,201, 40, 0, 82, 16, 48,184,116,185, 10,131,187,223,142,229,207, 46,199, 27,171,223,224, 21,141, +114,109,216,146, 99, 54, 3, 0,182,110,221,218,226,216,153, 51,103, 18,215, 50,190, 98,189,123, 69, 33, 38, 66, 77, 10, 11, 11, + 3,142, 42,168,213,106,178,122,245,106, 0, 8, 10, 95, 91, 10,127, 93, 93, 29, 27, 45, 11,232, 60,235,234,234,216, 54,221, 95, + 30, 37,128, 63, 0,248, 1,192, 39, 0,198, 1,120, 20,192,159,224, 88, 21, 18,104, 57, 75,167, 8, 0,105, 90,135,198,100,103, +101,250,246,226,179,178,178, 40,189, 94, 79,233,245,122,170,162,162, 2,236,119, 54,164,204,253,237,110,187, 39,176, 70, 69, 70, + 70,134,161,186,186,218,224,206, 64,224,254,246, 49, 85,174, 59,175,198,219,239, 27,254,130,125,254,249,231,110,133,159,162,168, + 86,226,159,153,153,201,139,243,215,138, 74, 24, 55, 46,198,244, 15,243,208, 39,238, 86,244,140, 14, 67,197,246, 10,135,248, 71, +118,118,236, 20, 34, 21,124,174, 41, 41, 41, 42,111,191,249,128, 33,192, 45,225,192,142,116,160, 71, 40, 48, 36,234,122,216, 63, +182, 19,240, 69,218,245,114,161,160, 40,202,237, 71, 8, 94,127,253,117,183,194, 63,120,240, 96,100,101,101, 97,245,220, 73, 56, + 94,126, 14,189,226,123, 3,166, 70, 62,222, 63,120, 70, 1,120,123,121,249, 95,232,176,187,240,123,183,158, 62,167,111, 95,208, +133,175,254,148,120,252,248, 3, 86,244,217,191,214,148,254,130,142,111, 52, 55, 98,204,204,251, 12,137,189,239, 65,147,201, 4, + 72,165,144,201,100,144, 74,165,144, 74,101, 56,115,230, 12,182,109,207, 63,111,177, 53,162,111,104, 44, 70, 62, 52, 98,236,188, +103,230, 9,246, 26,223,220, 61, 23,227,181,113,173,202,183,110,221, 74, 9,141, 4,176,226,143,190,239, 96,247,138,194,128, 61, +119,181, 90, 77,214,173, 91,135,161, 67,135, 98,253,250,245, 29, 50, 18,176, 96,193,130,164, 89,179,102,145, 83,167, 78, 25,170, +170,170,130,194, 87, 85, 85,133,170,170,170, 64,162, 9, 42, 0, 15, 1, 56, 10,224, 60,128, 94,112, 76,189,125, 22,192, 57,231, +199, 12, 17,205, 6, 49, 43,254,220,239,174,198,242, 13,153, 7,128,211,247,138,138,138, 10,244,232,209,163,149,129,192,150,185, + 51, 16,120, 54,174,126, 39,255, 61,246,216, 99,109,118,237, 92,177,114,231,245, 59, 23, 14,162,124,137,133, 25,149, 48, 78,187, + 7, 36, 98, 9, 48,118, 5,140,248, 12,248,216,225, 45, 18,253, 18,132,252,113, 61,104, 90,248, 68,103, 5, 5, 5, 37,220,251, +228, 99,238,117,247, 17,158,141,192,107, 31, 2,183,222, 2, 92,218, 41, 71,206, 6, 43,230,110,241, 92, 46,200,189, 39,193,109, + 31,185,201,126, 23,190, 88,133,136, 33, 10, 40, 7,188,128,207, 87,205,199,240,161,189, 48,104,210, 27,188,234,131,207,169, 63, +242, 72, 33,246,238, 85,243,233,203,167, 0, 16, 23,241,167,216,196, 63,127,250,245,249,122,248,124,224, 73,232,139, 92, 34, 1, +190,112,161,250, 2,198,107,198, 35,162,115, 20,236, 20,141,111,190,254, 15, 26,140, 70,164, 76,158,140,203,213,213,200,205,219, +134,167,159,154,219, 39, 84, 17, 10, 9, 9,193,132,187, 38, 20,255,100, 88,239,151,215,120,237,218,181,128,175,155, 43,254, 0, +156, 70,192,139,126, 71, 2,212,106, 53, 89,185,114, 37,250,247,119,220,207,126,253,250,161, 35, 69, 2, 92, 60,254,160,129,227, +253,179,223,253,185,214, 59,156,239,100, 8,128,112, 0, 67, 0,156, 4,208, 7, 64, 61,128, 90, 4,185, 91,238,247,128, 27, 54, + 17, 80,143, 30, 61, 84, 26,141,166, 85, 87,128,115,109,123, 0,104, 94,239, 94,168, 56,248,153,252,199, 55,226,224, 55, 88,239, +222, 83,184,159,175,247, 15, 0, 95,190,188, 18, 41,111,189, 13,122,236, 24,200, 0, 40, 15,156,198, 87,229, 53, 0, 0,122,236, + 66,216,126,236, 6,170,251,159, 4,139,148, 23, 65,226,141,154,169,159, 97,225, 83,231,240,243,179,203, 96,218,107, 69,175,110, +222,203,253, 53,160, 2, 53, 14, 54,111,222,236,176,134, 83, 30,196,193,170,106, 68, 12,143,192,249,162,114, 64, 17,138, 25, 11, +255,136,174,183, 76,106,207,119,209, 83,214,191, 95,117,226, 37,138,224, 46,250,224,149,187, 40,173, 8, 19,178, 39, 96, 70, 30, +144, 86,228,248, 94,148, 86,212,108, 28,200, 11, 78,243, 58, 7,163,165, 1,221,194,162, 65, 91, 26, 65, 36, 4,119,143, 30,141, +237,219,183, 91,214,189,253,182,130, 33, 4, 79,204,126, 2, 93,163,187,162,209,104, 4,109,167, 17, 17,210, 25, 54,137,205,175, +235,173,173,173,109, 49, 58, 64,104, 66, 96, 43,241,103,225,167, 17,160, 86,171,137, 86,171,197,232,209,163, 91,148, 15, 29, 58, + 20,111,190,249,102,187, 26, 1,109, 37,252, 44, 55,151,151,141, 2,248,177, 84,240,119, 0,142, 56,197,254, 81, 0,227, 1,148, + 1, 24, 6, 32, 31,192, 38, 0, 54,136, 8,200, 0, 32, 46,162, 72, 4,110,247,138,248,248,248,102,209, 79, 76, 76, 84,177,185, + 1,108,116, 32, 62, 62,222,192,118, 23,180, 87,195, 27, 76,248,234,235,231,120,255, 62, 49,253,195, 60,144,201,113,184,116,239, + 93,136,198, 24,132,205, 88, 15,250,194,101, 32,178, 51,100, 53,159, 97,231,186, 82, 64, 42,245,231,218, 3,182,154,143,190,244, + 7,140, 26, 1,196, 47, 60,142, 33,202,167,240,211,109, 26,224, 31,203, 60,150,183, 87, 4, 32, 43, 43, 11, 15,220, 61, 8, 99, +199, 12, 68,202,157,203,176,118,221, 7, 56, 89,122, 30,207, 62, 60, 10, 23,243,119,163,238, 90,125,176,158,135, 22, 93, 5,206, + 40,128, 79,129,230, 10,126, 48,197,223, 3, 39, 47, 84, 86, 86, 82,177,177,177,196,153,255,215,108, 16, 0,192,132,236, 9,144, + 23,156, 70, 65, 65,121,243, 72, 0,239, 9,129, 20, 24,134,129,157, 1, 8, 67, 35, 52, 76,129,217, 79, 62,169,120,237,213, 87, +209,179,103, 79,166, 79,175, 94, 18,139,201, 8, 59, 1, 8, 99, 7,195,248,142,104,229,228,228, 80,227,198,141, 35, 53, 53, 53, +168,175,175,111, 97, 56,186,140, 14,224, 61, 42, 64,173, 86,147,181,243, 79, 0,138,254,192,197,247, 90,239,160,232,143,181,243, + 79, 0, 60,141, 0,181, 90, 77,166, 76,153,162, 26, 58,116,168,161,166,166,166,213,246,216,216, 88, 76,153, 50, 69,133, 14,158, + 19, 16,168,247, 31, 96, 20,128,107, 48,244,134,163, 43, 96, 26, 0, 19, 68, 4,205, 0, 16, 50, 17,144,187,237,110,161,209,104, +220, 70, 1, 88,177,239,209,163,135, 74,171,213, 26,156,130, 8,141, 70,227, 53,169,208,155,119,232,199,248,250, 54, 25, 6,200, +122,247,222,146, 1,133,160,252,111,105, 8,153,177, 30,230,170,159, 33, 59,176, 30,182,188,133,160, 38,174,193,142, 63,165,226, +236,142, 51, 72, 89,253, 9, 32,107,159,153,157,151,233,129,162,213,219, 49,228,236, 4,224,138, 9, 75,199, 45,243, 90, 30,140, + 8,128,191,222,127,254,246,149,144,246,185, 3, 74, 12, 68,229,215,217,104,160, 8,254,251,243, 57,140, 61,126,158,215,233,236, +221,171,246, 40,246, 0,224,220,238,118, 63,190,226,239,225, 25, 13, 72, 24, 2,153, 3,128, 69, 90,209,117,225, 7,208,202,243, +103, 19, 6, 11, 10,202,221, 30, 31, 17, 22,129,170,186, 42,140,238,123, 15,204, 77, 22,192,108, 1,109,181, 97,185, 86, 11, 74, + 2, 73,163,201, 8,134,177,131,182, 19,132,202, 66,112,217,120, 25, 33,118,223,163,141,191,250,234,171,230,107,155, 51,103, 14, + 97,219,155, 43, 87,174,231,132, 93,184,112,129,247,117, 58, 68,216, 97, 4, 12,142,107,253,255, 79,157,177, 34,227,227, 33,224, + 43,214,206,253,200,232,209,163, 17, 27, 27,219,106,251,241,227,199,145,159,159,111,104, 47,241,119,122,227, 20, 27, 9, 8, 70, +191,191, 59,239, 63, 8, 81, 0, 22,227,157, 6, 65,147, 40,225,193, 53, 0,218, 4,172,231, 15, 0,137,137,137, 42,189, 94,111, + 96, 67,255, 30,140, 3, 85, 89, 89,153,175, 92, 0, 42, 88,222,188, 16, 49,225,107, 96,176,222,191, 59,225,103, 13, 29, 33,231, +123,180,188, 6,182, 31, 95,195, 37,124,139, 94, 19,215, 0,117,245, 40,207, 94,130,126, 11,222,193,197, 77, 75,128, 16, 25, 32, +105,159,153,157, 43, 77,192,224, 30,211,120,151,183, 71, 4, 32, 43, 43,203, 56,115,236, 61, 23,186, 48, 81,183, 54, 34, 68,145, +247,206, 66,188,191,243, 8,150, 62,122, 63,230,190,253, 41, 82,255,239,255,181,105, 52,200,219, 37,230,127,161,131,115, 18, 32, + 42, 80,227, 52,144, 80,191,183, 40, 64, 90, 81, 17,113, 39,254, 92,239,223, 23, 98,122,196,224,203,111,138,112,223,173,247, 33, +188,147, 18, 12, 67, 32, 33, 52, 24,138, 2, 33, 4,118, 2,208, 12, 1, 77,211, 48,215,153,176,235,208, 46,200,237,114,193, 73, +169,174,137, 78,127, 94, 56, 6,201, 49, 21,160,246,240,231,240,100, 4, 8, 21,127, 87, 35, 96,245,234,213,232,221,187,247,117, +195,190,188, 28, 89, 89, 89,232, 8,158,127,176, 13, 1,119,222,127,128, 81, 0, 0, 72, 2,112, 27,128,191,224,250,194, 79, 34, + 58,178, 1,208,163, 71, 15,149,107, 68,128,237,119,231, 26, 7,220,239, 1,122,240,130, 31,172, 32, 14, 3,116,235,253,251, 43, +252, 44,166,175,218,132,109, 0, 30,125, 43, 25, 68,191, 4,212, 99,107,113,180,188, 6, 84,215, 40,156,254,181,222,225,253, 11, +239, 2, 8, 10,142, 31, 63,222, 60,228,143,207,247, 96, 68, 0,132, 24, 7,155, 55,111,182, 2,104,152,159, 52,172,254,133, 53, +127,183,190,188, 92,107,233,222,185, 71,205,137,147,149, 61,231,158,252, 84,217, 78,194,207, 71,156,185, 93, 52,188,163, 0,109, + 53, 25,144, 59,241,103, 61,127, 0, 62, 19, 2, 23, 47, 94, 76,221,247,200,125,147, 13, 99, 74,242, 53,119,166,162,222, 82, 15, + 74, 2, 56, 6, 35, 49,176,219, 9, 24,154, 70,167,208, 8,236,175,251, 1,101, 7, 78, 35, 87,151, 91, 18,240,137,151, 63, 3, + 64,248, 48,192, 22, 70, 64,239, 74,156,186, 16,235,151,248,187, 26, 1,235,215,175, 71,100,100, 36,106,106,106,176,114,229, 74, +116,180,176,127, 48, 12, 1, 79,222,191,159, 81,128,158,112,100,253, 75, 0,140, 4,144, 1,160, 92,148,239, 32, 27, 0,109, 53, + 15,128,167,136,192,218,181,107, 85,174,134,130, 70,163, 17, 60, 97, 16, 87, 8, 58,194, 20,187, 92,239,159, 43,252, 90,173,150, +237,246,224,222, 87,222, 39,204, 26, 1,211,222,218, 8,146, 7,116,155,171, 67,201, 11,169,184, 63,235, 95, 64, 72, 8, 58, 41, +228,237,114,189,220, 49,254,238,190,251, 57, 15, 0, 13, 64,226,172, 91, 73,128,245,113,105,230,216,123,170, 94,200, 46,136, 91, +254,244,248,206, 49,189,146,172, 0,142,105, 52,154, 46,112,140, 47,246,171, 62,216, 71,110,239, 94, 53,155,241,239,143,113, 71, +249,242,224,133, 8,122, 48, 66,253, 66,224, 42,250,108, 68,160,107,215,174,110,173,179,253,123,247,239,136,189,253, 86,216,103, +210,199, 30,186,245,161, 97,209, 17,209,176,216, 44, 32,132, 64, 46,147,163,214,220,136,131,191,238,197,230,127,230, 64,117,135, + 74,149,139,220,128,207,241,205,221,115,145,147,147,131,178, 50,225,115, 0, 92, 55, 2, 16,144,248,115,249, 22, 46, 92, 72, 86, +175, 94,141,101,203,150,161, 35,247,249,115, 13,129,146,146, 18,191,142,245,182,143, 0,206, 41,112,140,247,183, 0,120, 9,192, + 33, 0,118, 81,190,221, 99,196,136, 17, 56,114,228, 8,178,179, 50, 91,205, 3,224, 58, 27,160,204,165,161,244,218,199,207,253, +237,186, 93,200, 98, 4,222,132,222,207, 40, 64, 64,104,171, 97,128,172, 49,162,211,233, 80, 92, 92,204, 84, 84, 84,112,133, 76, +165,215,235, 5,123, 55,211, 87,109, 2, 56, 19,255, 60,180,252,195,230,239,237,148, 13,227,179, 1, 99,136, 95,247,110, 29,128, +171,112, 12,255,153, 29,224, 57, 94,156,159, 52,172,105, 92,241,119,157,159,120,245, 19,232,116, 58,121,113,113,113,111,180,156, +206,218,175,250,104,235, 72,128,175,249,253,125,182,156,109,208, 37,224, 73,252,173, 41,253,129, 2,223,142,217,150,247,182, 82, +157,164, 74,114, 32,246, 32,198,220, 51, 6,125, 34,250, 0, 12,193,101, 75, 13,246,127,191, 31, 23, 79, 92,196,195,131, 31, 86, + 45, 90,180,168,221,235,131,107, 4, 4, 75,172,217, 72,192,205,146,240, 23, 64, 95,125,176,144,237,252,136, 16,122,227,178, 50, +249, 71, 0,218, 10, 25, 25, 25,110,197,222,101, 37, 54, 46, 12,238,230, 45,246, 37,180,254,162, 45,134, 1,102,101,101, 65,167, +211,209,197,197,197, 50,103,215, 1, 43,254, 15,123,185,110,183,112, 46,166,212, 22, 83, 41, 19, 47,229,237,210, 56,233,116,186, + 80,231,115,185,194, 89,100, 79, 79, 79,127, 50, 64,218,208,113,127,249,168, 84,167,211, 61, 88, 92, 92,140,226,226, 98, 11, 0, +133,243, 19, 12,225,167,120,142,247, 23, 44,210,206,237, 45,234, 75,168,112, 7,163, 75,160,178,178,146, 42, 74, 43, 34, 49, 11, + 99, 84,232,235,126,159,170,180, 34, 3,223,124,128, 13,239,110,160,222,121,231,157,164, 77,111,109, 66,108,255,219, 12, 0,240, +211,241,255,169, 38,141, 75,193,186, 15,214,149,108,193, 22,191,206, 51, 39, 39,135, 26, 63,126,124,171, 81, 1, 54, 91, 96, 35, +196,130, 45,214,191,181,108,127, 17, 29, 51, 10,224, 90,198,219, 0,240,229,137, 11,240,212,253,125,208, 73, 27,243, 7,235,120, +183,124, 26,141,134, 20, 23, 23,203,184,247,139, 27, 97, 17,104,160,148,180,145, 32,119,196, 70, 40, 2,128, 17, 32, 4,142,137, +249,195, 16,216,248, 94,182, 62,126, 41, 46, 46,102,199,149,213,199,199,199,119,207,202,202, 10,237, 8,247,178, 45,195,246,193, +228,174,172,172,164, 42,151, 86, 6,237, 30,188,248,226,139, 37,174,199,237,255,247,129,128,207,115,207,158, 61,162,184,138, 16, +141, 0, 30, 78, 52,229,239, 58,194, 34, 68,136, 16, 33, 66,132,136,155, 23, 18,241, 22,136, 16, 33, 66,132, 8, 17,162, 1, 32, + 66,132, 8, 17, 34, 68,136,248, 29,224,255, 3,225,148, 76, 97,126,153, 60, 69, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, }; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index c3ff9030093..acef8c9a2a4 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -103,6 +103,7 @@ #include "BSE_filesel.h" #include "BIF_gl.h" +#include "BIF_editaction.h" #include "BIF_editarmature.h" #include "BIF_editconstraint.h" #include "BIF_editdeform.h" @@ -3694,6 +3695,7 @@ static void editing_panel_lattice_type(Object *ob, Lattice *lt) void do_armbuts(unsigned short event) { Object *ob= OBACT; + bAction *act; switch(event) { case B_ARM_RECALCDATA: @@ -3731,45 +3733,125 @@ void do_armbuts(unsigned short event) if (ob && ob->pose) pose_clear_paths(ob); break; - - case B_POSELIB_NEW: - if (ob && ob->pose) - poselib_init_new(ob); - allqueue(REDRAWBUTSEDIT, 0); - break; + case B_POSELIB_ADDPOSE: if (ob && ob->pose) poselib_add_current_pose(ob, 1); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); break; case B_POSELIB_REPLACEP: if (ob && ob->pose) poselib_add_current_pose(ob, 2); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); break; case B_POSELIB_REMOVEP: if (ob && ob->pose) { - bAction *act= ob->pose->poselib; - bPoseLib *pl= act->poselib; - bPoseLibRef *plr= BLI_findlink(&pl->poses, pl->active_nr-1); + bAction *act= ob->poselib; + TimeMarker *marker= poselib_get_active_pose(act); - poselib_remove_pose(ob, plr); + poselib_remove_pose(ob, marker); } allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); break; case B_POSELIB_VALIDATE: - if (ob && ob->pose) { - bAction *act= ob->pose->poselib; - - poselib_validate_act(act); - } + if (ob && ob->pose) + poselib_validate_act(ob->poselib); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); break; case B_POSELIB_APPLYP: if (ob && ob->pose) poselib_preview_poses(ob, 1); allqueue(REDRAWBUTSEDIT, 0); break; + + /* note: copied from headerbuttons.c */ + case B_POSELIB_ALONE: //B_ACTALONE + if (ob && ob->id.lib==0) { + act= ob->poselib; + + if (act->id.us > 1) { + if (okee("Single user")) { + ob->poselib= copy_action(act); + act->id.us--; + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); + } + } + } + break; + case B_POSELIB_DELETE: //B_ACTIONDELETE + act= ob->poselib; + + if (act) + act->id.us--; + ob->poselib=NULL; + + BIF_undo_push("Unlink PoseLib"); + + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); + break; + case B_POSELIB_BROWSE: //B_ACTIONBROWSE: + { + ID *id, *idtest; + int nr= 1; + + if (ob == NULL) + break; + act= ob->poselib; + id= (ID *)act; + + if (G.buts->menunr == -2) { + activate_databrowse((ID *)ob->poselib, ID_AC, 0, B_POSELIB_BROWSE, &G.buts->menunr, do_armbuts); + return; + } + if (G.buts->menunr < 0) break; + + /* See if we have selected a valid action */ + for (idtest= G.main->action.first; idtest; idtest= idtest->next) { + if (nr == G.buts->menunr) { + break; + } + nr++; + } + + /* Store current action */ + if (!idtest) { + /* 'Add New' option: + * - make a copy of an exisiting action + * - or make a new empty action if no existing action + */ + if (act) { + idtest= (ID *)copy_action(act); + } + else { + /* a plain action */ + idtest=(ID *)add_empty_action("PoseLib"); + } + idtest->us--; + } + + if ((idtest != id) && (ob)) { + act= (bAction *)idtest; + + ob->poselib= act; + id_us_plus(idtest); + + if (id) id->us--; + + /* Update everything */ + BIF_undo_push("Browse PoseLibs"); + + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWHEADERS, 0); + } + } + break; } } @@ -4982,50 +5064,38 @@ static void editing_panel_links(Object *ob) /* poselib for armatures */ if (ob->type==OB_ARMATURE) { if ((ob->pose) && (ob->flag & OB_POSEMODE) && (G.obedit != ob)) { - bPose *pose= ob->pose; - bAction *act= pose->poselib; + bAction *act= ob->poselib; xco= 143; - uiDefBut(block, LABEL,0,"PoseLib:", xco, 154, 130,20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL,0, "Action (PoseLib):", xco, 154, 130,20, 0, 0, 0, 0, 0, ""); /* PoseLib Action */ - if (act) { - if (act->poselib==NULL) { - uiBlockSetCol(block, TH_REDALERT); - uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, REDRAWBUTSEDIT, "AC:", xco, 130, 140, 20, &pose->poselib, "Action to use as PoseLib - (Warning: this Action doesn't have a PoseLib)"); - uiBlockSetCol(block, TH_AUTO); - } - else { - uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, REDRAWBUTSEDIT, "AC:", xco, 130, 140, 20, &pose->poselib, "Action to use as PoseLib"); - } - } - uiDefBut(block, BUT, B_POSELIB_NEW, "New PoseLib", xco,110,70,20, 0, 0, 0, 0, 0, "Creates a new PoseLib"); - uiDefBut(block, BUT, B_POSELIB_VALIDATE, "Validate PoseLib", xco+70,110,70,20, 0, 0, 0, 0, 0, "Validates active PoseLib"); + uiBlockSetCol(block, TH_BUT_SETTING2); + std_libbuttons(block, 143, 130, 0, NULL, B_POSELIB_BROWSE, ID_AC, 0, (ID *)act, (ID *)ob, &(G.buts->menunr), B_POSELIB_ALONE, 0, B_POSELIB_DELETE, 0, 0); + uiBlockSetCol(block, TH_AUTO); + + uiDefBut(block, BUT, B_POSELIB_VALIDATE, "Auto-Sync PoseLib", xco,110,160,20, 0, 0, 0, 0, 0, "Syncs the current PoseLib with the poses available"); /* poselib pose editing controls */ - if ((act) && (act->poselib)) { - bPoseLib *pl= act->poselib; - bPoseLibRef *plr= BLI_findlink(&pl->poses, pl->active_nr-1); - int plr_count= BLI_countlist(&pl->poses); - char *menustr= poselib_build_poses_menu(pl, "PoseLib Poses"); + if ((act) && (act->markers.first)) { + TimeMarker *marker= poselib_get_active_pose(act); + int count= BLI_countlist(&act->markers); + char *menustr= poselib_build_poses_menu(act, "PoseLib Poses"); uiBlockBeginAlign(block); /* currently 'active' pose */ - uiDefButI(block, MENU, B_POSELIB_APPLYP, menustr, xco, 85,18,20, &pl->active_nr, 1, plr_count, 0, 0, "Browses Poses in PoseLib. Applies chosen pose."); + uiDefButI(block, MENU, B_POSELIB_APPLYP, menustr, xco, 85,18,20, &act->active_marker, 1, count, 0, 0, "Browses Poses in PoseLib. Applies chosen pose."); MEM_freeN(menustr); - if (pl->active_nr) { - but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", 161,85,140-18-20,20, plr->name, 0, 31, 0, 0, "Displays current PoseLib Pose name. Click to change."); - //uiButSetFunc(but, verify_vertexgroup_name_func, defGroup, NULL); - //uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob); - - but = uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, 263, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this PoseLib Pose from PoseLib"); + if (act->active_marker) { + uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current PoseLib Pose name. Click to change."); + uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this PoseLib Pose from PoseLib"); } /* add new poses */ - uiDefBut(block, BUT, B_POSELIB_ADDPOSE, "Add Pose", xco,65,70,20, 0, 0, 0, 0, 0, "Add current pose to PoseLib"); - uiDefBut(block, BUT, B_POSELIB_REPLACEP, "Replace Pose", xco+70,65,70,20, 0, 0, 0, 0, 0, "Replace existing PoseLib Pose with current pose"); + uiDefBut(block, BUT, B_POSELIB_ADDPOSE, "Add Pose", xco,65,80,20, 0, 0, 0, 0, 0, "Add current pose to PoseLib"); + uiDefBut(block, BUT, B_POSELIB_REPLACEP, "Replace Pose", xco+80,65,80,20, 0, 0, 0, 0, 0, "Replace existing PoseLib Pose with current pose"); uiBlockEndAlign(block); } } diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 58dfdd89df2..05a50fe4f16 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -883,7 +883,7 @@ void drawactionspace(ScrArea *sa, void *spacedata) glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); - if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { + if (curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) { if(G.v2d->scroll) { ofsx= curarea->winrct.xmin; ofsy= curarea->winrct.ymin; @@ -927,8 +927,10 @@ void drawactionspace(ScrArea *sa, void *spacedata) /* Draw current frame */ draw_cfra_action(); - /* Draw markers */ - draw_markers_timespace(0); + /* Draw markers (local behind scene ones, as local obscure scene markers) */ + if (act) + draw_markers_timespace(&act->markers, DRAW_MARKERS_LOCAL); + draw_markers_timespace(SCE_MARKERS, 0); /* Draw 'curtains' for preview */ draw_anim_preview_timespace(); diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c index fd3fa0df927..07442a541a5 100644 --- a/source/blender/src/drawipo.c +++ b/source/blender/src/drawipo.c @@ -2247,7 +2247,7 @@ void drawipospace(ScrArea *sa, void *spacedata) draw_anim_preview_timespace(); /* draw markers */ - draw_markers_timespace(0); + draw_markers_timespace(SCE_MARKERS, 0); /* restore viewport */ mywinset(sa->win); diff --git a/source/blender/src/drawnla.c b/source/blender/src/drawnla.c index ea49c05b322..a0b4c7f01b3 100644 --- a/source/blender/src/drawnla.c +++ b/source/blender/src/drawnla.c @@ -792,7 +792,7 @@ void drawnlaspace(ScrArea *sa, void *spacedata) draw_cfra_action(); /* draw markers */ - draw_markers_timespace(0); + draw_markers_timespace(SCE_MARKERS, 0); /* Draw preview 'curtains' */ draw_anim_preview_timespace(); diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 156a6c7b6c9..02f420dc641 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -1064,7 +1064,7 @@ void drawseqspace(ScrArea *sa, void *spacedata) } /* Draw markers */ - draw_markers_timespace(1); + draw_markers_timespace(SCE_MARKERS, DRAW_MARKERS_LINES); /* restore viewport */ mywinset(sa->win); diff --git a/source/blender/src/drawsound.c b/source/blender/src/drawsound.c index 17d340b802c..4fff327c5bb 100644 --- a/source/blender/src/drawsound.c +++ b/source/blender/src/drawsound.c @@ -220,7 +220,7 @@ void drawsoundspace(ScrArea *sa, void *spacedata) } draw_cfra_sound(spacedata); - draw_markers_timespace(0); + draw_markers_timespace(SCE_MARKERS, 0); /* restore viewport */ mywinset(curarea->win); diff --git a/source/blender/src/drawtime.c b/source/blender/src/drawtime.c index 3743d6c963e..52aba50c9cd 100644 --- a/source/blender/src/drawtime.c +++ b/source/blender/src/drawtime.c @@ -64,6 +64,7 @@ #include "BIF_language.h" #include "BSE_drawipo.h" +#include "BSE_time.h" #include "BSE_view.h" #include "blendef.h" @@ -84,7 +85,7 @@ /* ---- prototypes ------ */ void drawtimespace(ScrArea *, void *); - +/* draws a current frame indicator for the TimeLine */ static void draw_cfra_time(SpaceTime *stime) { float vec[2]; @@ -144,9 +145,13 @@ static void draw_cfra_time(SpaceTime *stime) } -static void draw_marker(TimeMarker *marker, int lines) +/* ---------- */ + +/* function to draw markers */ +static void draw_marker(TimeMarker *marker, int flag) { float xpos, ypixels, xscale, yscale; + int icon_id= 0; xpos = marker->frame; /* no time correction for framelen! space is drawn with old values */ @@ -161,7 +166,7 @@ static void draw_marker(TimeMarker *marker, int lines) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* verticle line */ - if (lines) { + if (flag & DRAW_MARKERS_LINES) { setlinestyle(3); if(marker->flag & SELECT) glColor4ub(255,255,255, 96); @@ -176,14 +181,20 @@ static void draw_marker(TimeMarker *marker, int lines) } /* 5 px to offset icon to align properly, space / pixels corrects for zoom */ - if(marker->flag & SELECT) - BIF_icon_draw(xpos*xscale-5.0, 12.0, ICON_MARKER_HLT); - else - BIF_icon_draw(xpos*xscale-5.0, 12.0, ICON_MARKER); + if (flag & DRAW_MARKERS_LOCAL) { + icon_id= (marker->flag & ACTIVE) ? ICON_PMARKER_ACT : + (marker->flag & SELECT) ? ICON_PMARKER_SEL : + ICON_PMARKER; + } + else { + icon_id= (marker->flag & SELECT) ? ICON_MARKER_HLT : + ICON_MARKER; + } + BIF_icon_draw(xpos*xscale-5.0, 12.0, icon_id); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); - + /* and the marker name too, shifted slightly to the top-right */ if(marker->name && marker->name[0]) { if(marker->flag & SELECT) { @@ -202,24 +213,27 @@ static void draw_marker(TimeMarker *marker, int lines) glScalef(xscale, yscale, 1.0); } -static void draw_markers_time(int lines) +/* Draw Scene-Markers for the TimeLine */ +static void draw_markers_time(int flag) { TimeMarker *marker; /* unselected markers are drawn at the first time */ - for(marker= G.scene->markers.first; marker; marker= marker->next) { - if(!(marker->flag & SELECT)) draw_marker(marker, lines); + for (marker= G.scene->markers.first; marker; marker= marker->next) { + if (!(marker->flag & SELECT)) draw_marker(marker, flag); } /* selected markers are drawn later ... selected markers have to cover unselected * markers laying at the same position as selected markers - * (jiri: it is hack, it could be solved better) */ - for(marker= G.scene->markers.first; marker; marker= marker->next) { - if(marker->flag & SELECT) draw_marker(marker, lines); + * (jiri: it is hack, it could be solved better) + */ + for (marker= G.scene->markers.first; marker; marker= marker->next) { + if (marker->flag & SELECT) draw_marker(marker, flag); } } -void draw_markers_timespace(int lines) +/* Draw specified set of markers for Animation Editors */ +void draw_markers_timespace(ListBase *markers, int flag) { TimeMarker *marker; float yspace, ypixels; @@ -233,21 +247,21 @@ void draw_markers_timespace(int lines) glTranslatef(0.0f, -11.0*yspace/ypixels, 0.0f); /* unselected markers are drawn at the first time */ - for(marker= G.scene->markers.first; marker; marker= marker->next) { - if(!(marker->flag & SELECT)) draw_marker(marker, lines); + for (marker= markers->first; marker; marker= marker->next) { + if (!(marker->flag & SELECT)) draw_marker(marker, flag); } /* selected markers are drawn later ... selected markers have to cover unselected * markers laying at the same position as selected markers */ - for(marker= G.scene->markers.first; marker; marker= marker->next) { - if(marker->flag & SELECT) draw_marker(marker, lines); + for (marker= markers->first; marker; marker= marker->next) { + if (marker->flag & SELECT) draw_marker(marker, flag); } glTranslatef(0.0f, -G.v2d->cur.ymin, 0.0f); glTranslatef(0.0f, 11.0*yspace/ypixels, 0.0f); - } + void draw_anim_preview_timespace() { /* only draw this if preview range is set */ diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index cb032ddfb61..c70f20aed89 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -2227,9 +2227,11 @@ void column_select_action_keys(int mode) } /* some quick defines for borderselect modes */ -#define ACTEDIT_BORDERSEL_ALL 0 -#define ACTEDIT_BORDERSEL_FRA 1 -#define ACTEDIT_BORDERSEL_CHA 2 +enum { + ACTEDIT_BORDERSEL_ALL = 0, + ACTEDIT_BORDERSEL_FRA, + ACTEDIT_BORDERSEL_CHA +}; /* borderselect: for keyframes only */ void borderselect_action (void) @@ -2351,7 +2353,7 @@ static void mouse_action (int selectmode) bActionChannel *achan= NULL; bConstraintChannel *conchan= NULL; IpoCurve *icu= NULL; - TimeMarker *marker; + TimeMarker *marker, *pmarker; void *act_channel; short sel, act_type; @@ -2363,9 +2365,63 @@ static void mouse_action (int selectmode) if (datatype == ACTCONT_ACTION) act= (bAction *)data; act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan); - marker=find_nearest_marker(1); + marker= find_nearest_marker(SCE_MARKERS, 1); + pmarker= (act) ? find_nearest_marker(&act->markers, 1) : NULL; + + if (marker) { + /* what about scene's markers? */ + if (selectmode == SELECT_REPLACE) { + deselect_markers(0, 0); + marker->flag |= SELECT; + } + else if (selectmode == SELECT_INVERT) { + if (marker->flag & SELECT) + marker->flag &= ~SELECT; + else + marker->flag |= SELECT; + } + else if (selectmode == SELECT_ADD) + marker->flag |= SELECT; + else if (selectmode == SELECT_SUBTRACT) + marker->flag &= ~SELECT; - if (act_channel) { + std_rmouse_transform(transform_markers); + + allqueue(REDRAWMARKER, 0); + } + else if (pmarker) { + /* action's markers are drawn behind scene markers */ + if (selectmode == SELECT_REPLACE) { + action_set_activemarker(act, pmarker, 1); + pmarker->flag |= SELECT; + } + else if (selectmode == SELECT_INVERT) { + if (pmarker->flag & SELECT) { + pmarker->flag &= ~SELECT; + action_set_activemarker(act, NULL, 0); + } + else { + pmarker->flag |= SELECT; + action_set_activemarker(act, pmarker, 0); + } + } + else if (selectmode == SELECT_ADD) { + pmarker->flag |= SELECT; + action_set_activemarker(act, pmarker, 0); + } + else if (selectmode == SELECT_SUBTRACT) { + pmarker->flag &= ~SELECT; + action_set_activemarker(act, NULL, 0); + } + + // TODO: local-markers cannot be moved atm... + //std_rmouse_transform(transform_markers); + + allqueue(REDRAWACTION, 0); + allqueue(REDRAWBUTSEDIT, 0); + } + else if (act_channel) { + /* must have been a channel */ switch (act_type) { case ACTTYPE_ICU: icu= (IpoCurve *)act_channel; @@ -2410,27 +2466,6 @@ static void mouse_action (int selectmode) allqueue(REDRAWOOPS, 0); allqueue(REDRAWBUTSALL, 0); } - else if (marker) { - /* not channel, so maybe marker */ - if (selectmode == SELECT_REPLACE) { - deselect_markers(0, 0); - marker->flag |= SELECT; - } - else if (selectmode == SELECT_INVERT) { - if (marker->flag & SELECT) - marker->flag &= ~SELECT; - else - marker->flag |= SELECT; - } - else if (selectmode == SELECT_ADD) - marker->flag |= SELECT; - else if (selectmode == SELECT_SUBTRACT) - marker->flag &= ~SELECT; - - std_rmouse_transform(transform_markers); - - allqueue(REDRAWMARKER, 0); - } } /* lefthand side - mouse-click */ @@ -2699,7 +2734,7 @@ void bottom_sel_action () if (VISIBLE_ACHAN(achan)) { if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) { /* take it out off the chain keep data */ - BLI_remlink (&act->chanbase, achan); + BLI_remlink(&act->chanbase, achan); /* add at end */ BLI_addtail(&act->chanbase, achan); achan->flag |= ACHAN_MOVED; @@ -2720,6 +2755,141 @@ void bottom_sel_action () allqueue(REDRAWNLA, 0); } +/* **************************************************** */ +/* ACTION MARKERS (PoseLib features) */ +/* NOTE: yes, these duplicate code from edittime.c a bit, but these do a bit more... + * These could get merged with those someday if need be... (Aligorith, 20071230) + */ + +/* Makes the given marker the active one + * - deselect indicates whether unactive ones should be deselected too + */ +void action_set_activemarker (bAction *act, TimeMarker *active, short deselect) +{ + TimeMarker *marker; + int index= 0; + + /* sanity checks */ + if (act == NULL) + return; + act->active_marker= 0; + + /* set appropriate flags for all markers */ + for (marker=act->markers.first; marker; marker=marker->next, index++) { + /* only active may be active */ + if (marker == active) { + act->active_marker= index + 1; + marker->flag |= (SELECT|ACTIVE); + } + else { + if (deselect) + marker->flag &= ~(SELECT|ACTIVE); + else + marker->flag &= ~ACTIVE; + } + } +} + +/* Adds a local marker to the active action */ +void action_add_localmarker (bAction *act, int frame) +{ + TimeMarker *marker; + char name[64]; + + /* sanity checks */ + if (act == NULL) + return; + + /* get name of marker */ + sprintf(name, "Pose"); + if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) + return; + + /* add marker to action - replaces any existing marker there */ + for (marker= act->markers.first; marker; marker= marker->next) { + if (marker->frame == frame) { + BLI_strncpy(marker->name, name, sizeof(marker->name)); + break; + } + } + if (marker == NULL) { + marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker"); + + BLI_strncpy(marker->name, name, sizeof(marker->name)); + marker->frame= frame; + + BLI_addtail(&act->markers, marker); + } + + /* sets the newly added marker as the active one */ + action_set_activemarker(act, marker, 1); + + BIF_undo_push("Action Add Marker"); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + +/* Renames the active local marker to the active action */ +void action_rename_localmarker (bAction *act) +{ + TimeMarker *marker; + char name[64]; + int val; + + /* sanity checks */ + if (act == NULL) + return; + + /* get active marker to rename */ + if (act->active_marker == 0) + return; + else + val= act->active_marker; + + if (val <= 0) return; + marker= BLI_findlink(&act->markers, val-1); + if (marker == NULL) return; + + /* get name of marker */ + sprintf(name, marker->name); + if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) + return; + + /* copy name */ + BLI_strncpy(marker->name, name, sizeof(marker->name)); + + /* undo and update */ + BIF_undo_push("Action Rename Marker"); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); +} + +/* Deletes all selected markers, and adjusts things as appropriate */ +void action_remove_localmarkers (bAction *act) +{ + TimeMarker *marker, *next; + + /* sanity checks */ + if (act == NULL) + return; + + /* remove selected markers */ + for (marker= act->markers.first; marker; marker= next) { + next= marker->next; + + if (marker->flag & SELECT) + BLI_freelinkN(&act->markers, marker); + } + + /* clear active just in case */ + act->active_marker= 0; + + /* undo and update */ + BIF_undo_push("Action Remove Marker(s)"); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); +} + /* **************************************************** */ /* EVENT HANDLING */ @@ -2860,6 +3030,18 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt) allqueue(REDRAWMARKER, 0); break; + case LKEY: + /* poselib manipulation - only for actions */ + if (datatype == ACTCONT_ACTION) { + if (G.qual == LR_SHIFTKEY) + action_add_localmarker(data, CFRA); + else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) + action_rename_localmarker(data); + else if (G.qual == LR_ALTKEY) + action_remove_localmarkers(data); + } + break; + case MKEY: if (G.qual & LR_SHIFTKEY) { /* mirror keyframes */ diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 54aea493e88..82c897236a2 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -1465,7 +1465,7 @@ void mouse_select_ipo(void) if(G.sipo->editipo==0) return; get_status_editipo(); - marker=find_nearest_marker(1); + marker=find_nearest_marker(SCE_MARKERS, 1); /* map ipo-points for editing if scaled ipo */ if (NLA_IPO_SCALED) { diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c index fc79c265f8d..a75f5a211b7 100644 --- a/source/blender/src/editnla.c +++ b/source/blender/src/editnla.c @@ -1257,7 +1257,7 @@ static void mouse_nla(int selectmode) /* Try object ipo or ob-constraint ipo selection */ base= get_nearest_nlachannel_ob_key(&selx, &sel); - marker=find_nearest_marker(1); + marker=find_nearest_marker(SCE_MARKERS, 1); if (base) { isdone= 1; diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index f1e2f957610..887737e0dad 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -791,7 +791,7 @@ void mouse_select_seq(void) int hand,seldir; TimeMarker *marker; - marker=find_nearest_marker(1); + marker=find_nearest_marker(0, 1); if (marker) { int oldflag; diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c index befcd574ac4..dfb5ce6e371 100644 --- a/source/blender/src/editsound.c +++ b/source/blender/src/editsound.c @@ -173,7 +173,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt) getmouseco_areawin(mval); areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); - marker = find_nearest_marker(0); + marker = find_nearest_marker(SCE_MARKERS, 0); if (marker) { if ((G.qual & LR_SHIFTKEY)==0) deselect_markers(0, 0); diff --git a/source/blender/src/edittime.c b/source/blender/src/edittime.c index f5c6fe5a95e..1520cb6c696 100644 --- a/source/blender/src/edittime.c +++ b/source/blender/src/edittime.c @@ -473,7 +473,7 @@ void get_minmax_markers(short sel, float *first, float *last) *last= max; } -TimeMarker *find_nearest_marker(int clip_y) +TimeMarker *find_nearest_marker(ListBase *markers, int clip_y) { TimeMarker *marker; float xmin, xmax; @@ -483,7 +483,7 @@ TimeMarker *find_nearest_marker(int clip_y) getmouseco_areawin (mval); /* first clip selection in Y */ - if((clip_y) && (mval[1] > 30)) + if ((clip_y) && (mval[1] > 30)) return NULL; mval[0]-=7; @@ -494,7 +494,7 @@ TimeMarker *find_nearest_marker(int clip_y) xmin= rectf.xmin; xmax= rectf.xmax; - for(marker= G.scene->markers.first; marker; marker= marker->next) { + for (marker= markers->first; marker; marker= marker->next) { if ((marker->frame > xmin) && (marker->frame <= xmax)) { return marker; } @@ -877,9 +877,9 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt) case RIGHTMOUSE: /* select/deselect marker */ getmouseco_areawin(mval); areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); - + cfra= find_nearest_marker_time(dx); - + if (G.qual && LR_SHIFTKEY) select_timeline_marker_frame(cfra, 1); else diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index 5fa5c6fb97e..a5e2f8b11a3 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -174,7 +174,10 @@ enum { ACTMENU_MARKERS_DUPLICATE, ACTMENU_MARKERS_DELETE, ACTMENU_MARKERS_NAME, - ACTMENU_MARKERS_MOVE + ACTMENU_MARKERS_MOVE, + ACTMENU_MARKERS_LOCALADD, + ACTMENU_MARKERS_LOCALRENAME, + ACTMENU_MARKERS_LOCALDELETE }; void do_action_buttons(unsigned short event) @@ -1103,6 +1106,16 @@ static void do_action_markermenu(void *arg, int event) case ACTMENU_MARKERS_MOVE: transform_markers('g', 0); break; + + case ACTMENU_MARKERS_LOCALADD: + action_add_localmarker(G.saction->action, CFRA); + break; + case ACTMENU_MARKERS_LOCALDELETE: + action_remove_localmarkers(G.saction->action); + break; + case ACTMENU_MARKERS_LOCALRENAME: + action_rename_localmarker(G.saction->action); + break; } allqueue(REDRAWMARKER, 0); @@ -1130,7 +1143,15 @@ static uiBlock *action_markermenu(void *arg_unused) menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_NAME, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Marker|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_MOVE, ""); + + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Local Marker|Shift L", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALADD, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename Local Marker|Ctrl Shift L", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALRENAME, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Local Marker|Alt L", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALDELETE, ""); if(curarea->headertype==HEADERTOP) { uiBlockSetDirection(block, UI_DOWN); diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 505206ed6e0..dd3d6d9b33b 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -325,6 +325,7 @@ int std_libbuttons(uiBlock *block, short xco, short yco, } if( GS(id->name)==ID_IP) len= 110; + else if((yco) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib) else if(yco) len= 140; // comes from button panel else len= 120; @@ -932,6 +933,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWACTION, 0); allqueue(REDRAWNLA, 0); allqueue(REDRAWIPO, 0); + allqueue(REDRAWBUTSEDIT, 0); break; case B_ACTIONBROWSE: if (!ob) @@ -1030,6 +1032,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWNLA, 0); allqueue(REDRAWACTION, 0); allqueue(REDRAWHEADERS, 0); + allqueue(REDRAWBUTSEDIT, 0); } } @@ -1703,7 +1706,8 @@ void do_global_buttons2(short event) if(act->id.lib) { if(okee("Make local")) { make_local_action(act); - allqueue(REDRAWACTION,0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWBUTSEDIT, 0); } } } @@ -1711,12 +1715,13 @@ void do_global_buttons2(short event) case B_ACTALONE: if(ob && ob->id.lib==0) { act= ob->action; - + if(act->id.us>1) { if(okee("Single user")) { ob->action=copy_action(act); act->id.us--; allqueue(REDRAWACTION, 0); + allqueue(REDRAWBUTSEDIT, 0); } } } diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index b87a5ea6e97..2d11f149ed7 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -63,6 +63,7 @@ #include "BSE_editipo.h" #include "BDR_drawaction.h" +#include "BSE_time.h" #include "BIF_poselib.h" #include "BIF_interface.h" @@ -72,6 +73,7 @@ #include "BIF_toets.h" #include "BIF_toolbox.h" + #include "blendef.h" #include "PIL_time.h" /* sleep */ @@ -86,22 +88,21 @@ * It acts as a kind of "glorified clipboard for poses", allowing for naming of poses. * * Features: - * - PoseLibs are simply normal Actions, but with a poselib + * - PoseLibs are simply normal Actions * - Each "pose" is simply a set of keyframes that occur on a particular frame - * -> a bPoseLibRef struct is used to identify and label poses in the Action - * -> all bPoseLibRefs are stored in the order they were added - * -> keys for poses should occur on each positively numbered frame (starting from frame 1) + * -> a set of TimeMarkers that belong to each Action, help 'label' where a 'pose' can be + * found in the Action * - The Scrollwheel or PageUp/Down buttons when used in a special mode or after pressing/holding * [a modifier] key, cycles through the poses available for the active pose's poselib, allowing the * animator to preview what action best suits that pose */ /* ************************************************************* */ -/* gets list of poses in poselib as a string */ -char *poselib_build_poses_menu (bPoseLib *pl, char title[]) +/* gets list of poses in poselib as a string usable for pupmenu() */ +char *poselib_build_poses_menu (bAction *act, char title[]) { DynStr *pupds= BLI_dynstr_new(); - bPoseLibRef *plr; + TimeMarker *marker; char *str; char buf[64]; int i; @@ -110,14 +111,14 @@ char *poselib_build_poses_menu (bPoseLib *pl, char title[]) sprintf(buf, "%s%%t|", title); BLI_dynstr_append(pupds, buf); - /* loop through keyingsets, adding them */ - for (plr=pl->poses.first, i=1; plr; plr=plr->next, i++) { - BLI_dynstr_append(pupds, plr->name); + /* loop through markers, adding them */ + for (marker=act->markers.first, i=1; marker; marker=marker->next, i++) { + BLI_dynstr_append(pupds, marker->name); sprintf(buf, "%%x%d", i); BLI_dynstr_append(pupds, buf); - if (plr->next) + if (marker->next) BLI_dynstr_append(pupds, "|"); } @@ -128,75 +129,28 @@ char *poselib_build_poses_menu (bPoseLib *pl, char title[]) return str; } -/* finds an unique name for pose to be added to poselib */ -void poselib_unique_pose_name (bPoseLib *pl, char name[]) -{ - bPoseLibRef *plr; - char tempname[32]; - int number = 1, exists = 0; - char *dot; - - /* See if we are given an empty string */ - if (name[0] == '\0') { - /* give it default name first */ - strcpy(name, "Pose"); - } - - /* See if we even need to do this */ - for (plr= pl->poses.first; plr; plr= plr->next) { - if (!strcmp(name, plr->name)) { - exists = 1; - break; - } - } - - if (exists == 0) - return; - - /* Strip off the suffix */ - dot = strchr(name, '.'); - if (dot) - *dot=0; - - for (number = 1; number <= 999; number++) { - sprintf(tempname, "%s.%03d", name, number); - - exists = 0; - for (plr= pl->poses.first; plr; plr= plr->next) { - if (strcmp(name, tempname)==0) { - exists = 1; - break; - } - } - if (exists == 0) { - BLI_strncpy(name, tempname, 32); - return; - } - } -} - /* gets the first available frame in poselib to store a pose on * - frames start from 1, and a pose should occur on every frame... 0 is error! */ -int poselib_get_free_index (bPoseLib *pl) +int poselib_get_free_index (bAction *act) { - bPoseLibRef *plr; + TimeMarker *marker; int low=0, high=0; /* sanity checks */ - if (ELEM(NULL, pl, pl->poses.first)) return 1; + if (ELEM(NULL, act, act->markers.first)) return 1; /* loop over poses finding various values (poses are not stored in chronological order) */ - for (plr= pl->poses.first; plr; plr= plr->next) { + for (marker= act->markers.first; marker; marker= marker->next) { /* only increase low if value is 1 greater than low, to find "gaps" where * poses were removed from the poselib */ - if (plr->frame == (low + 1)) + if (marker->frame == (low + 1)) low++; /* value replaces high if it is the highest value encountered yet */ - if (plr->frame > high) - high= plr->frame; + if (marker->frame > high) + high= marker->frame; } /* - if low is not equal to high, then low+1 is a gap @@ -208,46 +162,41 @@ int poselib_get_free_index (bPoseLib *pl) return (high + 1); } +/* returns the active pose for a poselib */ +TimeMarker *poselib_get_active_pose (bAction *act) +{ + if ((act) && (act->active_marker)) + return BLI_findlink(&act->markers, act->active_marker-1); + else + return NULL; +} + /* ************************************************************* */ /* Initialise a new poselib (whether it is needed or not) */ -bPoseLib *poselib_init_new (Object *ob) +bAction *poselib_init_new (Object *ob) { - bPose *pose= (ob) ? ob->pose : NULL; - bAction *act; - bPoseLib *pl; - - if (ELEM(NULL, ob, pose)) + /* sanity checks - only for armatures */ + if (ELEM(NULL, ob, ob->pose)) return NULL; - /* init pose's poselib action (unlink old one if there) */ - if (pose->poselib) - pose->poselib->id.us--; - pose->poselib= add_empty_action("PoseLib"); - act= pose->poselib; + /* init object's poselib action (unlink old one if there) */ + if (ob->poselib) + ob->poselib->id.us--; + ob->poselib= add_empty_action("PoseLib"); - /* init actions's poselib data */ - if (act->poselib == NULL) - act->poselib= MEM_callocN(sizeof(bPoseLib), "bPoseLib"); - pl= act->poselib; - - return pl; + return ob->poselib; } /* Initialise a new poselib (checks if that needs to happen) */ -bPoseLib *poselib_validate (Object *ob) +bAction *poselib_validate (Object *ob) { - bPose *pose= (ob) ? ob->pose : NULL; - bAction *act= (pose) ? pose->poselib : NULL; - bPoseLib *pl= (act) ? act->poselib : NULL; - - if (ELEM(NULL, ob, pose)) + if (ELEM(NULL, ob, ob->pose)) return NULL; - - if (ELEM(NULL, act, pl)) + else if (ob->poselib == NULL) return poselib_init_new(ob); else - return pl; + return ob->poselib; } @@ -258,8 +207,7 @@ void poselib_validate_act (bAction *act) { ListBase keys = {NULL, NULL}; ActKeyColumn *ak; - bPoseLib *pl; - bPoseLibRef *plr, *plrn; + TimeMarker *marker, *markern; /* validate action and poselib */ if (act == NULL) { @@ -267,49 +215,44 @@ void poselib_validate_act (bAction *act) return; } - if (act->poselib == NULL) - act->poselib= MEM_callocN(sizeof(bPoseLib), "bPoseLib"); - pl= act->poselib; - /* determine which frames have keys */ action_to_keylist(act, &keys, NULL); /* for each key, make sure there is a correspnding pose */ for (ak= keys.first; ak; ak= ak->next) { /* check if any pose matches this */ - for (plr= pl->poses.first; plr; plr= plr->next) { - if (IS_EQ(plr->frame, ak->cfra)) { - plr->flag = 1; + for (marker= act->markers.first; marker; marker= marker->next) { + if (IS_EQ(marker->frame, ak->cfra)) { + marker->flag = -1; break; } } /* add new if none found */ - if (plr == NULL) { - char name[32]; + if (marker == NULL) { + char name[64]; /* add pose to poselib */ - plr= MEM_callocN(sizeof(bPoseLibRef), "bPoseLibRef"); + marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker"); strcpy(name, "Pose"); - poselib_unique_pose_name(pl, name); - BLI_strncpy(plr->name, name, sizeof(plr->name)); + BLI_strncpy(marker->name, name, sizeof(marker->name)); - plr->frame= (int)ak->cfra; - plr->flag= 1; + marker->frame= (int)ak->cfra; + marker->flag= -1; - BLI_addtail(&pl->poses, plr); + BLI_addtail(&act->markers, marker); } } /* remove all untagged poses (unused), and remove all tags */ - for (plr= pl->poses.first; plr; plr= plrn) { - plrn= plr->next; + for (marker= act->markers.first; marker; marker= markern) { + markern= marker->next; - if (plr->flag == 0) - BLI_freelinkN(&pl->poses, plr); + if (marker->flag != -1) + BLI_freelinkN(&act->markers, marker); else - plr->flag = 0; + marker->flag = 0; } /* free temp memory */ @@ -353,13 +296,12 @@ void poselib_add_current_pose (Object *ob, int val) bArmature *arm= (ob) ? ob->data : NULL; bPose *pose= (ob) ? ob->pose : NULL; bPoseChannel *pchan; - bPoseLib *pl; - bPoseLibRef *plr; + TimeMarker *marker; bAction *act; bActionChannel *achan; IpoCurve *icu; int frame; - char name[32]; + char name[64]; /* sanity check */ if (ELEM3(NULL, ob, arm, pose)) @@ -367,7 +309,7 @@ void poselib_add_current_pose (Object *ob, int val) /* mode - add new or replace existing */ if (val == 0) { - if (pose->poselib && pose->poselib->poselib->poses.first) { + if ((ob->poselib) && (ob->poselib->markers.first)) { val= pupmenu("PoseLib Add Current Pose%t|Add New%x1|Replace Existing%x2"); if (val <= 0) return; } @@ -375,24 +317,23 @@ void poselib_add_current_pose (Object *ob, int val) val= 1; } - if ((pose->poselib) && (val == 2)) { + if ((ob->poselib) && (val == 2)) { char *menustr; /* get poselib */ - act= pose->poselib; - pl= act->poselib; + act= ob->poselib; /* get the pose to replace */ - menustr= poselib_build_poses_menu(pl, "Replace PoseLib Pose"); + menustr= poselib_build_poses_menu(act, "Replace PoseLib Pose"); val= pupmenu(menustr); if (menustr) MEM_freeN(menustr); if (val <= 0) return; - plr= BLI_findlink(&pl->poses, val-1); - if (plr == NULL) return; + marker= BLI_findlink(&act->markers, val-1); + if (marker == NULL) return; /* get the frame from the poselib */ - frame= plr->frame; + frame= marker->frame; } else { /* get name of pose */ @@ -401,18 +342,26 @@ void poselib_add_current_pose (Object *ob, int val) return; /* get/initialise poselib */ - pl= poselib_validate(ob); - act= pose->poselib; + act= poselib_validate(ob); /* validate name and get frame */ - poselib_unique_pose_name(pl, name); - frame= poselib_get_free_index(pl); + frame= poselib_get_free_index(act); - /* add pose to poselib */ - plr= MEM_callocN(sizeof(bPoseLibRef), "bPoseLibRef"); - BLI_strncpy(plr->name, name, sizeof(plr->name)); - plr->frame= frame; - BLI_addtail(&pl->poses, plr); + /* add pose to poselib - replaces any existing pose there */ + for (marker= act->markers.first; marker; marker= marker->next) { + if (marker->frame == frame) { + BLI_strncpy(marker->name, name, sizeof(marker->name)); + break; + } + } + if (marker == NULL) { + marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker"); + + BLI_strncpy(marker->name, name, sizeof(marker->name)); + marker->frame= frame; + + BLI_addtail(&act->markers, marker); + } } /* loop through selected posechannels, keying their pose to the action */ @@ -448,7 +397,7 @@ void poselib_add_current_pose (Object *ob, int val) } /* store new 'active' pose number */ - pl->active_nr= BLI_countlist(&pl->poses); + act->active_marker= BLI_countlist(&act->markers); BIF_undo_push("PoseLib Add Pose"); allqueue(REDRAWBUTSEDIT, 0); @@ -456,12 +405,11 @@ void poselib_add_current_pose (Object *ob, int val) /* This tool removes the pose that the user selected from the poselib (or the provided pose) */ -void poselib_remove_pose (Object *ob, bPoseLibRef *plr) +void poselib_remove_pose (Object *ob, TimeMarker *marker) { bPose *pose= (ob) ? ob->pose : NULL; - bAction *act= (pose) ? pose->poselib : NULL; + bAction *act= (ob) ? ob->poselib : NULL; bActionChannel *achan; - bPoseLib *pl= (act) ? act->poselib : NULL; char *menustr; int val; @@ -470,24 +418,24 @@ void poselib_remove_pose (Object *ob, bPoseLibRef *plr) error("PoseLib is only for Armatures in PoseMode"); return; } - if (ELEM(NULL, act, pl)) { - error("Pose doesn't have a valid PoseLib"); + if (act == NULL) { + error("Object doesn't have PoseLib data"); return; } /* get index (and pointer) of pose to remove */ - if (plr == NULL) { - menustr= poselib_build_poses_menu(pl, "Remove PoseLib Pose"); + if (marker == NULL) { + menustr= poselib_build_poses_menu(act, "Remove PoseLib Pose"); val= pupmenu(menustr); if (menustr) MEM_freeN(menustr); if (val <= 0) return; - plr= BLI_findlink(&pl->poses, val-1); - if (plr == NULL) return; + marker= BLI_findlink(&act->markers, val-1); + if (marker == NULL) return; } else { /* only continue if pose belongs to poselib */ - if (BLI_findindex(&pl->poses, plr) == -1) + if (BLI_findindex(&act->markers, marker) == -1) return; } @@ -501,7 +449,7 @@ void poselib_remove_pose (Object *ob, bPoseLibRef *plr) for (icu= ipo->curve.first; icu; icu= icu->next) { for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { /* check if remove... */ - if (IS_EQ(bezt->vec[1][0], plr->frame)) { + if (IS_EQ(bezt->vec[1][0], marker->frame)) { delete_icu_key(icu, i); break; } @@ -510,14 +458,15 @@ void poselib_remove_pose (Object *ob, bPoseLibRef *plr) } /* remove poselib from list */ - BLI_freelinkN(&pl->poses, plr); + BLI_freelinkN(&act->markers, marker); /* fix active pose number */ - pl->active_nr= 0; + act->active_marker= 0; /* undo + redraw */ BIF_undo_push("PoseLib Remove Pose"); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); } @@ -525,10 +474,9 @@ void poselib_remove_pose (Object *ob, bPoseLibRef *plr) void poselib_rename_pose (Object *ob) { bPose *pose= (ob) ? ob->pose : NULL; - bAction *act= (pose) ? pose->poselib : NULL; - bPoseLib *pl= (act) ? act->poselib : NULL; - bPoseLibRef *plr; - char *menustr, name[32]; + bAction *act= (ob) ? ob->poselib : NULL; + TimeMarker *marker; + char *menustr, name[64]; int val; /* check if valid poselib */ @@ -536,34 +484,32 @@ void poselib_rename_pose (Object *ob) error("PoseLib is only for Armatures in PoseMode"); return; } - if (ELEM(NULL, act, pl)) { - error("Pose doesn't have a valid PoseLib"); + if (act == NULL) { + error("Object doesn't have a valid PoseLib"); return; } /* get index of pose to remove */ - menustr= poselib_build_poses_menu(pl, "Rename PoseLib Pose"); + menustr= poselib_build_poses_menu(act, "Rename PoseLib Pose"); val= pupmenu(menustr); if (menustr) MEM_freeN(menustr); if (val <= 0) return; - plr= BLI_findlink(&pl->poses, val-1); - if (plr == NULL) return; + marker= BLI_findlink(&act->markers, val-1); + if (marker == NULL) return; /* get name of pose */ - sprintf(name, plr->name); + sprintf(name, marker->name); if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) return; - - /* validate name */ - poselib_unique_pose_name(pl, name); // hmm what happens with the old pose's name... /* copy name */ - BLI_strncpy(plr->name, name, sizeof(plr->name)); + BLI_strncpy(marker->name, name, sizeof(marker->name)); /* undo and update */ BIF_undo_push("PoseLib Rename Pose"); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); } @@ -574,23 +520,17 @@ typedef struct tPoseLib_Backup { struct tPoseLib_Backup *next, *prev; bPoseChannel *pchan; - - float oldloc[3]; - float oldsize[3]; - float oldquat[4]; - - int oldflag; + bPoseChannel olddata; } tPoseLib_Backup; /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ -static void poselib_backup_posecopy (ListBase *backups, bPose *pose) +static void poselib_backup_posecopy (ListBase *backups, bPose *pose, bAction *act) { - bAction *poselib= pose->poselib; bActionChannel *achan; bPoseChannel *pchan; /* for each posechannel that has an actionchannel in */ - for (achan= poselib->chanbase.first; achan; achan= achan->next) { + for (achan= act->chanbase.first; achan; achan= achan->next) { /* try to find posechannel */ pchan= get_pose_channel(pose, achan->name); @@ -600,11 +540,8 @@ static void poselib_backup_posecopy (ListBase *backups, bPose *pose) plb= MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup"); - VECCOPY(plb->oldloc, pchan->loc); - VECCOPY(plb->oldsize, pchan->size); - QUATCOPY(plb->oldquat, pchan->quat); - plb->pchan= pchan; + memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel)); BLI_addtail(backups, plb); } @@ -617,14 +554,11 @@ static void poselib_backup_restore (ListBase *backups) tPoseLib_Backup *plb; for (plb= backups->first; plb; plb= plb->next) { - VECCOPY(plb->pchan->loc, plb->oldloc); - VECCOPY(plb->pchan->size, plb->oldsize); - VECCOPY(plb->pchan->quat, plb->oldquat); - - plb->pchan->flag = plb->oldflag; + memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel)); } } + /* ---------------------------- */ /* Applies the appropriate stored pose from the pose-library to the current pose @@ -632,14 +566,14 @@ static void poselib_backup_restore (ListBase *backups) * - gets the string to print in the header * - this code is based on the code for extract_pose_from_action in blenkernel/action.c */ -static void poselib_apply_pose (Object *ob, bPoseLibRef *plr, char headerstr[]) +static void poselib_apply_pose (Object *ob, TimeMarker *marker, char headerstr[]) { bPose *pose= ob->pose; bPoseChannel *pchan; - bAction *act= pose->poselib; + bAction *act= ob->poselib; bActionChannel *achan; IpoCurve *icu; - int frame= plr->frame; + int frame= marker->frame; /* start applying - only those channels which have a key at this point in time! */ for (achan= act->chanbase.first; achan; achan= achan->next) { @@ -662,11 +596,13 @@ static void poselib_apply_pose (Object *ob, bPoseLibRef *plr, char headerstr[]) if (found) break; } - /* apply pose */ + /* apply pose - only if posechannel selected? */ if (found) { pchan= get_pose_channel(pose, achan->name); - if (pchan) { + if ( (pchan) && (pchan->bone) && + (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) ) + { /* Evaluates and sets the internal ipo values */ calc_ipo(achan->ipo, frame); /* This call also sets the pchan flags */ @@ -686,9 +622,8 @@ static void poselib_apply_pose (Object *ob, bPoseLibRef *plr, char headerstr[]) /* Auto-keys/tags bones affected by the pose used from the poselib */ static void poselib_keytag_pose (Object *ob) { - bPose *pose= ob->pose; bPoseChannel *pchan; - bAction *act= pose->poselib; + bAction *act= ob->poselib; bActionChannel *achan; /* start tagging/keying */ @@ -735,6 +670,35 @@ static void poselib_keytag_pose (Object *ob) /* ---------------------------- */ +/* This helper function is called during poselib_preview_poses to find the + * pose to preview next (after a change event) + */ +static TimeMarker *poselib_preview_get_next (bAction *act, TimeMarker *current, int step) +{ + if (step) { + TimeMarker *marker, *next; + + /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate + * until step == 0. At this point, marker should be the correct marker. + */ + if (step > 0) { + for (marker=current; marker && step; marker=next, step--) + next= (marker->next) ? marker->next : act->markers.first; + } + else { + for (marker=current; marker && step; marker=next, step++) + next= (marker->prev) ? marker->prev : act->markers.last; + } + + /* don't go anywhere if for some reason an error occurred */ + return (marker) ? marker : current; + } + else + return current; +} + +/* ---------------------------- */ + /* defines for poselib_preview_poses --> ret_val values */ enum { PL_PREVIEW_RUNNING = 0, @@ -759,9 +723,8 @@ void poselib_preview_poses (Object *ob, short apply_active) bPose *pose= (ob) ? (ob->pose) : NULL; bArmature *arm= (ob) ? (ob->data) : NULL; - bAction *act= (pose) ? (pose->poselib) : NULL; - bPoseLib *pl= (act) ? (act->poselib) : NULL; - bPoseLibRef *plr= (pl == NULL) ? NULL : (pl->active_nr) ? BLI_findlink(&pl->poses, pl->active_nr-1) : pl->poses.first; + bAction *act= (ob) ? (ob->poselib) : NULL; + TimeMarker *marker= poselib_get_active_pose(act); Base *base; short ret_val= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING; @@ -770,21 +733,21 @@ void poselib_preview_poses (Object *ob, short apply_active) char headerstr[200]; /* check if valid poselib */ - if (ELEM(NULL, ob, pose)) { + if (ELEM3(NULL, ob, pose, arm)) { error("PoseLib is only for Armatures in PoseMode"); return; } - if (ELEM(NULL, act, pl)) { - error("Pose doesn't have a valid PoseLib"); + if (act == NULL) { + error("Object doesn't have a valid PoseLib"); return; } - if (plr == NULL) { - error("PoseLib has no poses to preview"); + if (marker == NULL) { + error("PoseLib has no poses to preview/apply"); return; } /* make backup of current pose for restoring pose */ - poselib_backup_posecopy(&backups, pose); + poselib_backup_posecopy(&backups, pose, act); /* set depsgraph flags */ /* make sure the lock is set OK, unlock can be accidentally saved? */ @@ -805,7 +768,7 @@ void poselib_preview_poses (Object *ob, short apply_active) firsttime = 0; /* pose should be the right one to draw */ - poselib_apply_pose(ob, plr, headerstr); + poselib_apply_pose(ob, marker, headerstr); /* old optimize trick... this enforces to bypass the depgraph * - note: code copied from transform_generics.c -> recalcData() @@ -827,7 +790,7 @@ void poselib_preview_poses (Object *ob, short apply_active) /* do header print - if interactively previewing */ if (ret_val == PL_PREVIEW_RUNNING) { - sprintf(headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", plr->name); + sprintf(headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", marker->name); headerprint(headerstr); } @@ -866,17 +829,31 @@ void poselib_preview_poses (Object *ob, short apply_active) ret_val= PL_PREVIEW_CONFIRM; break; - /* change to previous pose - go back to end of list if no previous (cyclic) */ + /* change to previous pose (cyclic) */ case PAGEUPKEY: case WHEELUPMOUSE: - plr= (plr->prev) ? plr->prev : pl->poses.last; + case RIGHTARROWKEY: + marker= poselib_preview_get_next(act, marker, -1); redraw= PL_PREVIEW_REDRAWALL; break; - /* change to next pose - go back to start of list if no next (cyclic) */ + /* change to next pose (cyclic) */ case PAGEDOWNKEY: case WHEELDOWNMOUSE: - plr= (plr->next) ? plr->next : pl->poses.first; + case LEFTARROWKEY: + marker= poselib_preview_get_next(act, marker, 1); + redraw= PL_PREVIEW_REDRAWALL; + break; + + /* jump 5 poses (cyclic, back) */ + case DOWNARROWKEY: + marker= poselib_preview_get_next(act, marker, -5); + redraw= PL_PREVIEW_REDRAWALL; + break; + + /* jump 5 poses (cyclic, forward) */ + case UPARROWKEY: + marker= poselib_preview_get_next(act, marker, 5); redraw= PL_PREVIEW_REDRAWALL; break; @@ -931,7 +908,7 @@ void poselib_preview_poses (Object *ob, short apply_active) poselib_keytag_pose(ob); /* change active pose setting */ - pl->active_nr= BLI_findindex(&pl->poses, plr) + 1; + act->active_marker= BLI_findindex(&act->markers, marker) + 1; /* Update event for pose and deformation children */ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); From 65164a9e41cac5f39c7ceb0a82f914f2780c244d Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Sun, 30 Dec 2007 16:41:31 +0000 Subject: [PATCH 85/99] Python API ---------- tex->image attribute setter needed call to BKE_image_signal(), otherwise image would not appear when render. --- source/blender/python/api2_2x/Texture.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Texture.c b/source/blender/python/api2_2x/Texture.c index 66ed88df8d0..a8b5441acfc 100644 --- a/source/blender/python/api2_2x/Texture.c +++ b/source/blender/python/api2_2x/Texture.c @@ -1,5 +1,5 @@ /* - * $Id: Texture.c 12535 2007-11-09 10:29:19Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -32,6 +32,7 @@ #include "Texture.h" /*This must come first*/ #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_main.h" #include "BKE_idprop.h" #include "BKE_library.h" @@ -1572,6 +1573,7 @@ static int Texture_setImage( BPy_Texture * self, PyObject * value ) } self->texture->ima = blimg; + BKE_image_signal(blimg, &self->texture->iuser, IMA_SIGNAL_RELOAD ); id_us_plus( &blimg->id ); return 0; From 4260b054f4cbd37eb7a0bea1d5b335eca7b3e0f2 Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Sun, 30 Dec 2007 16:47:38 +0000 Subject: [PATCH 86/99] =?UTF-8?q?Python=20API=20----------=20Fix=20warning?= =?UTF-8?q?=20about=20implicit=20declaration=20of=20function=20=E2=80=98se?= =?UTF-8?q?t=5Fmipmap=E2=80=99.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/blender/python/api2_2x/Blender.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 2bcc9d21da4..eb9856c72fc 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -1,5 +1,6 @@ /* * $Id$ + * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -36,6 +37,7 @@ struct ID; /*keep me up here */ /* for open, close in Blender_Load */ #include #include "BDR_editobject.h" /* exit_editmode() */ +#include "BDR_drawmesh.h" /* set_mipmap() */ #include "BIF_usiblender.h" #include "BLI_blenlib.h" #include "BLO_writefile.h" From 71f8eaa04b40a72cd460057f46f29f8050a81c7b Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Sun, 30 Dec 2007 21:10:08 +0000 Subject: [PATCH 87/99] - Reactor particle target text was hidden in ui by distribution buttons. - Particle system tab had wrong coloring of buttons. --- source/blender/src/buttons_object.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index d69f5232b37..dc33f2d2ac4 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4235,7 +4235,9 @@ static void object_panel_particle_system(Object *ob) /* browse buttons */ uiBlockSetCol(block, TH_BUT_SETTING2); butx= std_libbuttons(block, butx, buty, 0, NULL, B_PARTBROWSE, ID_PA, 0, id, idfrom, &(G.buts->menunr), B_PARTALONE, 0, B_PARTDELETE, 0, 0); - + + uiBlockSetCol(block, TH_AUTO); + partact=psys_get_current_num(ob)+1; totpart=BLI_countlist(&ob->particlesystem); sprintf(str, "%d Part", totpart); @@ -4339,7 +4341,7 @@ static void object_panel_particle_system(Object *ob) } uiBlockEndAlign(block); - buty=50; + buty=30; if(part->type==PART_REACTOR) { ParticleSystem *tpsys=0; From d00d1f1c89f217e485e18020ff0bac087ffcd77f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Dec 2007 23:27:35 +0000 Subject: [PATCH 88/99] Routine purge of compiler warnings * Most were uninitialised vars * Fixed whitespace in a few places * The change I made in rendercore.c -> do_bake_shade() was for an uninitialised var, but I hope it does't cause any rendering errors... --- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/include/BDR_editobject.h | 1 + .../blender/render/intern/source/rendercore.c | 12 ++++----- source/blender/src/buttons_object.c | 1 - source/blender/src/editobject.c | 25 ++++++++++--------- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index de4f4555823..fd22579ea67 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1467,7 +1467,7 @@ void makeBevelList(Object *ob) BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; float *data, *data_a, *v1, *v2, min, inp, x1, x2, y1, y2, vec[3]; struct bevelsort *sortdata, *sd, *sd1; - int a, b, len, nr, poly, resolu; + int a, b, nr, poly, resolu, len=0; /* this function needs an object, because of tflag and upflag */ cu= ob->data; diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index 93e7873fe55..b38ee8d3939 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -81,6 +81,7 @@ void make_links(short event); void make_duplilist_real(void); void apply_objects_locrot(void); void apply_objects_visual_tx(void); +void apply_object(void); /* old transform */ void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 5b9a275ad32..3eda349eef9 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1976,15 +1976,15 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if(bs->actob) { Isect isec, minisec; float co[3], minco[3]; - int hit, sign, dir; + int hit, sign, dir=1; /* intersect with ray going forward and backward*/ hit= 0; memset(&minisec, 0, sizeof(minisec)); minco[0]= minco[1]= minco[2]= 0.0f; - + VECCOPY(bs->dir, shi->vn); - + for(sign=-1; sign<=1; sign+=2) { memset(&isec, 0, sizeof(isec)); VECCOPY(isec.start, shi->co); @@ -1992,7 +1992,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) isec.faceorig= (RayFace*)vlr; isec.oborig= RAY_OBJECT_SET(&R, obi); isec.userdata= bs; - + if(bake_intersect_tree(R.raytree, &isec, shi->vn, sign, co)) { if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) { minisec= isec; @@ -2014,13 +2014,11 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) obi= RAY_OBJECT_GET(&R, minisec.ob); quad= (minisec.isect == 2); VECCOPY(shi->co, minco); - + u= -minisec.u; v= -minisec.v; bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v); } - - } if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index dc33f2d2ac4..8451a4c8afd 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3752,7 +3752,6 @@ static void object_panel_particle_extra(Object *ob) ParticleSettings *part; short butx=0, buty=160, butw=150, buth=20; static short vgnum=0; - int event; if (psys==NULL) return; part=psys->part; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 5c1742467b7..eea97e15f00 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -3700,6 +3700,7 @@ void apply_objects_locrot( void ) { Base *base, *basact; Object *ob; + bArmature *arm; Mesh *me; Curve *cu; Nurb *nu; @@ -3714,21 +3715,23 @@ void apply_objects_locrot( void ) if TESTBASELIB(base) { ob= base->object; if(ob->type==OB_MESH) { + me= ob->data; + if(me->id.us>1) { error("Can't apply to a multi user mesh, doing nothing."); - return 0; + return; } if(me->key) { error("Can't apply to a mesh with vertex keys, doing nothing."); - return 0; + return; } } - else if (ob->type==OB_ARMATURE){ - bArmature *arm; + else if (ob->type==OB_ARMATURE) { arm= ob->data; + if(arm->id.us>1) { error("Can't apply to a multi user armature, doing nothing."); - return 0; + return; } } else if ELEM(ob->type, OB_CURVE, OB_SURF) { @@ -3736,11 +3739,11 @@ void apply_objects_locrot( void ) if(cu->id.us>1) { error("Can't apply to a multi user curve, doing nothing."); - return 0; + return; } if(cu->key) { error("Can't apply to a curve with vertex keys, doing nothing."); - return 0; + return; } } } @@ -3752,7 +3755,7 @@ void apply_objects_locrot( void ) for (base= FIRSTBASE; base; base= base->next) { if TESTBASELIB(base) { ob= base->object; - + if(ob->type==OB_MESH) { object_to_mat3(ob, mat); me= ob->data; @@ -3778,15 +3781,13 @@ void apply_objects_locrot( void ) change = 1; } - else if (ob->type==OB_ARMATURE){ - bArmature *arm; - + else if (ob->type==OB_ARMATURE) { object_to_mat3(ob, mat); arm= ob->data; /* see checks above */ + apply_rot_armature(ob, mat); - apply_rot_armature (ob, mat); /* Reset the object's transforms */ ob->size[0]= ob->size[1]= ob->size[2]= 1.0; ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; From 5e4d32a9ffa7157a40bbd4d1d821c6dad860af0d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Dec 2007 12:03:26 +0000 Subject: [PATCH 89/99] Improvements to File->External Data->Make Paths Relative & Make Paths Absolute, made when testing peach blend files wont have path issues when sent to the renderfarm. * log failed path conversions * clean the path so //foo/../foo/ is removed (not sure why but some peach files had this problem) Also added a function to util.c BLI_cleanup_file, same as BLI_cleanup_dir but dosnt add a slash at the end. --- source/blender/blenlib/BLI_blenlib.h | 3 +- source/blender/blenlib/BLI_bpath.h | 6 +-- source/blender/blenlib/intern/bpath.c | 55 ++++++++++++++++++++++----- source/blender/blenlib/intern/util.c | 16 +++++--- source/blender/src/header_info.c | 31 ++++++++++----- 5 files changed, 83 insertions(+), 28 deletions(-) diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index bcb51fa1393..eb13ddc318c 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -135,7 +135,8 @@ void BLI_dlist_reinit(struct DynamicList *dlist); * converts it to a regular full path. * Also removes garbage from directory paths, like /../ or double slashes etc */ -void BLI_cleanup_dir(const char *relabase, char *dir); +void BLI_cleanup_file(const char *relabase, char *dir); +void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */ /** * Blender's path code replacement function. diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 32d20c4b13e..e932c39eb06 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -54,7 +54,7 @@ void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path /* high level funcs */ /* creates a text file with missing files if there are any */ -struct Text * checkMissingFiles(void); -void makeFilesRelative(int *tot, int *changed, int *failed, int *linked); -void makeFilesAbsolute(int *tot, int *changed, int *failed, int *linked); +void checkMissingFiles(char *txtname ); +void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked); +void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked); void findMissingFiles(char *str); diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 2548c059064..a6c71a836f5 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -303,7 +303,7 @@ static void bpathToText(Text *btxt, struct BPathIterator *bpi) } /* high level function */ -Text *checkMissingFiles(void) { +void checkMissingFiles( char *txtname ) { Text *btxt = NULL; struct BPathIterator bpi; @@ -320,25 +320,29 @@ Text *checkMissingFiles(void) { BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded ); if (!BLI_exists(filepath_expanded)) { - if (!btxt) - btxt = add_empty_text( "missing_files.txt" ); - + if (!btxt) { + btxt = add_empty_text( "missing_files.log" ); + if (txtname) { + BLI_strncpy(txtname, btxt->id.name+2, 24); + } + } bpathToText(btxt, &bpi); files_missing = 1; } BLI_bpathIterator_step(&bpi); } - return btxt; } /* dont log any errors at the moment, should probably do this */ -void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { +void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked) { struct BPathIterator bpi; char *filepath, *libpath; /* be sure there is low chance of the path being too short */ char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE]; + Text *btxt = NULL; + *tot = *changed = *failed = *linked = 0; BLI_bpathIterator_init(&bpi); @@ -351,15 +355,32 @@ void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { (*linked)++; } else { /* local data, use the blend files path */ BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative)); + /* Important BLI_cleanup_dir runs before the path is made relative + * because it wont work for paths that start with "//../" */ + BLI_cleanup_file(G.sce, filepath_relative); /* fix any /foo/../foo/ */ BLI_makestringcode(G.sce, filepath_relative); /* be safe and check the length */ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) { + if (!btxt) { + btxt = add_empty_text( "missing_no_rel.log" ); + if (txtname) { + BLI_strncpy(txtname, btxt->id.name+2, 24); + } + } + bpathToText(btxt, &bpi); (*failed)++; } else { if(strncmp(filepath_relative, "//", 2)==0) { strcpy(filepath, filepath_relative); (*changed)++; } else { + if (!btxt) { + btxt = add_empty_text( "missing_no_rel.log" ); + if (txtname) { + BLI_strncpy(txtname, btxt->id.name+2, 24); + } + } + bpathToText(btxt, &bpi); (*failed)++; } } @@ -372,13 +393,15 @@ void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) { /* dont log any errors at the moment, should probably do this - * Verry similar to makeFilesRelative - keep in sync! */ -void makeFilesAbsolute(int *tot, int *changed, int *failed, int *linked) { +void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked) { struct BPathIterator bpi; char *filepath, *libpath; /* be sure there is low chance of the path being too short */ char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE]; + Text *btxt = NULL; + *tot = *changed = *failed = *linked = 0; BLI_bpathIterator_init(&bpi); @@ -391,15 +414,29 @@ void makeFilesAbsolute(int *tot, int *changed, int *failed, int *linked) { (*linked)++; } else { /* get the expanded path and check it is relative or too long */ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_absolute ); - - /* safe be safe, check the length */ + BLI_cleanup_file(G.sce, filepath_absolute); /* fix any /foo/../foo/ */ + /* to be safe, check the length */ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) { + if (!btxt) { + btxt = add_empty_text( "missing_no_abs.log" ); + if (txtname) { + BLI_strncpy(txtname, btxt->id.name+2, 24); + } + } + bpathToText(btxt, &bpi); (*failed)++; } else { if(strncmp(filepath_absolute, "//", 2)) { strcpy(filepath, filepath_absolute); (*changed)++; } else { + if (!btxt) { + btxt = add_empty_text( "missing_no_abs.log" ); + if (txtname) { + BLI_strncpy(txtname, btxt->id.name+2, 24); + } + } + bpathToText(btxt, &bpi); (*failed)++; } } diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 7c94cc80847..d1b2efa28c7 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -776,6 +776,16 @@ int BLI_strcaseeq(char *a, char *b) { */ void BLI_cleanup_dir(const char *relabase, char *dir) +{ + BLI_cleanup_file(relabase, dir); +#ifdef WIN32 + strcat(dir, "\\"); +#else + strcat(dir, "/"); +#endif +} + +void BLI_cleanup_file(const char *relabase, char *dir) { short a; char *start, *eind; @@ -814,9 +824,7 @@ void BLI_cleanup_dir(const char *relabase, char *dir) dir[a] = 0; } } - - strcat(dir, "\\"); -#else +#else if(dir[0]=='.') { /* happens, for example in FILE_MAIN */ dir[0]= '/'; dir[1]= 0; @@ -850,8 +858,6 @@ void BLI_cleanup_dir(const char *relabase, char *dir) if (a<=0) break; } } - - strcat(dir, "/"); #endif } diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 552201445d1..97b5341fda1 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -956,8 +956,11 @@ static void do_info_externalfiles(void *arg, int event) if (G.relbase_valid) { int tot,changed,failed,linked; char str[512]; - makeFilesRelative(&tot, &changed, &failed, &linked); - sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); + char txtname[24]; /* text block name */ + txtname[0] = '\0'; + makeFilesRelative(txtname, &tot, &changed, &failed, &linked); + if (failed) sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked); + else sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); pupmenu(str); } else { pupmenu("Can't set relative paths with an unsaved blend file"); @@ -967,22 +970,30 @@ static void do_info_externalfiles(void *arg, int event) { int tot,changed,failed,linked; char str[512]; - makeFilesAbsolute(&tot, &changed, &failed, &linked); + char txtname[24]; /* text block name */ + txtname[0] = '\0'; + makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked); sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); + if (failed) sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked); + else sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked); + pupmenu(str); } break; case 12: /* check images exist */ { - /* Its really text but only care about the name */ - ID *btxt = (ID *)checkMissingFiles(); + char txtname[24]; /* text block name */ + txtname[0] = '\0'; - if (btxt) { - char str[128]; - sprintf(str, "Missing files listed in Text \"%s\"", btxt->name+2); - error(str); - } else { + /* run the missing file check */ + checkMissingFiles( txtname ); + + if (txtname == '\0') { okee("No external files missing"); + } else { + char str[128]; + sprintf(str, "Missing files listed in Text \"%s\"", txtname ); + error(str); } } break; From be207a7e4c08f1ea683c0600887e91da86753f76 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Dec 2007 12:13:30 +0000 Subject: [PATCH 90/99] disallow editing the path of an indirectly linked library in the outliner --- source/blender/src/outliner.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 3e969e4ca9c..3b957b5f142 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -1917,9 +1917,11 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even if (G.qual & LR_CTRLKEY) { if(ELEM8(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) error("Cannot edit builtin name"); - else if(tselem->id->lib) + else if(tselem->id->lib) { error_libdata(); - else { + } else if(te->idcode == ID_LI && te->parent) { + error("Cannot edit the path of an indirectly linked library"); + } else { tselem->flag |= TSE_TEXTBUT; } } else { From 9afd6135d65ad55ad1214316e7d2448c5e78a95a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Dec 2007 12:47:10 +0000 Subject: [PATCH 91/99] made dupli's respect render and view restrict flags (from the outliner) This means one group can contain proxy objects to display in the 3d view as well as hi quality models that are only rendered. - again for peach tree's. --- source/blender/blenkernel/intern/anim.c | 70 +++++++++++++++---------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 76b897f5cb7..0b733f9c068 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -878,41 +878,53 @@ static void font_duplilist(ListBase *lb, Object *par, int level) /* ***************************** */ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level) { - if(ob->transflag & OB_DUPLI) { - if(ob->transflag & OB_DUPLIPARTS) { - ParticleSystem *psys = ob->particlesystem.first; - for(; psys; psys=psys->next) - new_particle_duplilist(duplilist, id, ob, psys, level+1); + if((ob->transflag & OB_DUPLI)==0) + return; + + /* Should the dupli's be greated for this object? - Respect restrict flags */ + if (G.rendering) { + if (ob->restrictflag & OB_RESTRICT_RENDER) { + return; } - else if(ob->transflag & OB_DUPLIVERTS) { - if(ob->type==OB_MESH) { - vertex_duplilist(duplilist, id, ob, par_space_mat, level+1); - } - else if(ob->type==OB_FONT) { - if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, ob, level+1); - } - } + } else { + if (ob->restrictflag & OB_RESTRICT_VIEW) { + return; } - else if(ob->transflag & OB_DUPLIFACES) { - if(ob->type==OB_MESH) - face_duplilist(duplilist, id, ob, par_space_mat, level+1); - } - else if(ob->transflag & OB_DUPLIFRAMES) { - if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, ob, level+1); - } - } else if(ob->transflag & OB_DUPLIGROUP) { - DupliObject *dob; - - group_duplilist(duplilist, ob, level+1); /* now recursive */ + } - if (level==0) { - for(dob= duplilist->first; dob; dob= dob->next) - Mat4CpyMat4(dob->ob->obmat, dob->mat); + if(ob->transflag & OB_DUPLIPARTS) { + ParticleSystem *psys = ob->particlesystem.first; + for(; psys; psys=psys->next) + new_particle_duplilist(duplilist, id, ob, psys, level+1); + } + else if(ob->transflag & OB_DUPLIVERTS) { + if(ob->type==OB_MESH) { + vertex_duplilist(duplilist, id, ob, par_space_mat, level+1); + } + else if(ob->type==OB_FONT) { + if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ + font_duplilist(duplilist, ob, level+1); } } } + else if(ob->transflag & OB_DUPLIFACES) { + if(ob->type==OB_MESH) + face_duplilist(duplilist, id, ob, par_space_mat, level+1); + } + else if(ob->transflag & OB_DUPLIFRAMES) { + if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ + frames_duplilist(duplilist, ob, level+1); + } + } else if(ob->transflag & OB_DUPLIGROUP) { + DupliObject *dob; + + group_duplilist(duplilist, ob, level+1); /* now recursive */ + + if (level==0) { + for(dob= duplilist->first; dob; dob= dob->next) + Mat4CpyMat4(dob->ob->obmat, dob->mat); + } + } } /* note; group dupli's already set transform matrix. see note in group_duplilist() */ From 8208d5d0beb20871ef93b89b959567871b5187b6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Dec 2007 22:18:04 +0000 Subject: [PATCH 92/99] Fix for check missing files, edited some tooltips - (Show key shortcuts for PLAY and RENDER) --- source/blender/src/buttons_scene.c | 20 ++++++++++---------- source/blender/src/header_info.c | 2 +- source/blender/src/header_time.c | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 820daeef6db..4c8aeb2443c 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1912,7 +1912,7 @@ static void render_panel_render(void) if(uiNewPanel(curarea, block, "Render", "Render", 320, 0, 318, 204)==0) return; uiBlockBeginAlign(block); - uiDefBut(block, BUT,B_DORENDER,"RENDER", 369, 164, 191,37, 0, 0, 0, 0, 0, "Start the rendering"); + uiDefBut(block, BUT,B_DORENDER,"RENDER", 369, 164, 191,37, 0, 0, 0, 0, 0, "Render the current frame (F12)"); #ifndef DISABLE_YAFRAY /* yafray: on request, render engine menu is back again, and moved to Render panel */ uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1", @@ -1924,10 +1924,10 @@ static void render_panel_render(void) uiBlockBeginAlign(block); uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)"); - uiDefButS(block, ROW,B_DIFF,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Sets oversample level to 5"); - uiDefButS(block, ROW,B_DIFF,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Sets oversample level to 8 (Recommended)"); - uiDefButS(block, ROW,B_DIFF,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Sets oversample level to 11"); - uiDefButS(block, ROW,B_DIFF,"16", 462,88,29,20,&G.scene->r.osa,2.0,16.0, 0, 0, "Sets oversample level to 16"); + uiDefButS(block, ROW,B_DIFF,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Render 5 samples per pixel for smooth edges (Fast)"); + uiDefButS(block, ROW,B_DIFF,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Render 8 samples per pixel for smooth edges (Recommended)"); + uiDefButS(block, ROW,B_DIFF,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Render 11 samples per pixel for smooth edges (High Quality)"); + uiDefButS(block, ROW,B_DIFF,"16", 462,88,29,20,&G.scene->r.osa,2.0,16.0, 0, 0, "Render 16 samples per pixel for smooth edges (Highest Quality)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); @@ -1973,7 +1973,7 @@ static void render_panel_render(void) uiDefButS(block, MENU, B_DIFF,str, 565,34,60,20, &G.scene->r.filtertype, 0, 0, 0, 0, "Set sampling filter for antialiasing"); uiDefButF(block, NUM,B_DIFF,"", 627,34,60,20,&G.scene->r.gauss,0.5, 1.5, 10, 2, "Sets the filter size"); - uiDefButBitI(block, TOG, R_BORDER, REDRAWVIEWCAM, "Border", 565,13,122,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image"); + uiDefButBitI(block, TOG, R_BORDER, REDRAWVIEWCAM, "Border", 565,13,122,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image (Shift+B to set in the camera view)"); uiBlockEndAlign(block); } @@ -1987,7 +1987,7 @@ static void render_panel_anim(void) if(uiNewPanel(curarea, block, "Anim", "Render", 640, 0, 318, 204)==0) return; - uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Start rendering a sequence"); + uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Render the animation to disk (from first to last frame)"); uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockBeginAlign(block); @@ -1996,12 +1996,12 @@ static void render_panel_anim(void) uiBlockEndAlign(block); uiBlockSetCol(block, TH_AUTO); - uiDefBut(block, BUT,B_PLAYANIM, "PLAY",692,40,94,33, 0, 0, 0, 0, 0, "Play animation of rendered images/avi (searches Pics: field)"); + uiDefBut(block, BUT,B_PLAYANIM, "PLAY",692,40,94,33, 0, 0, 0, 0, 0, "Play rendered images/avi animation (Ctrl+F11), (Play Hotkeys: A-Noskip, P-PingPong)"); uiDefButS(block, NUM, B_RTCHANGED, "rt:",789,40,95,33, &G.rt, -1000.0, 1000.0, 0, 0, "General testing/debug button"); uiBlockBeginAlign(block); - uiDefButI(block, NUM,REDRAWSEQ,"Sta:",692,10,94,24, &G.scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "The start frame of the animation"); - uiDefButI(block, NUM,REDRAWSEQ,"End:",789,10,95,24, &G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0, "The end frame of the animation"); + uiDefButI(block, NUM,REDRAWSEQ,"Sta:",692,10,94,24, &G.scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "The start frame of the animation (inclusive)"); + uiDefButI(block, NUM,REDRAWSEQ,"End:",789,10,95,24, &G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0, "The end frame of the animation (inclusive)"); uiBlockEndAlign(block); } diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 97b5341fda1..9f1a31a940a 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -988,7 +988,7 @@ static void do_info_externalfiles(void *arg, int event) /* run the missing file check */ checkMissingFiles( txtname ); - if (txtname == '\0') { + if (txtname[0] == '\0') { okee("No external files missing"); } else { char str[128]; diff --git a/source/blender/src/header_time.c b/source/blender/src/header_time.c index 53b22fc4e39..3da566bf418 100644 --- a/source/blender/src/header_time.c +++ b/source/blender/src/header_time.c @@ -469,27 +469,27 @@ void time_buttons(ScrArea *sa) uiDefButI(block, NUM, REDRAWALL,"Start:", xco,0, 4.5*XIC, YIC, &G.scene->r.psfra,MINFRAMEF, MAXFRAMEF, 0, 0, - "The start frame of the animation preview"); + "The start frame of the animation preview (inclusive)"); xco += 4.5*XIC; uiDefButI(block, NUM, REDRAWALL,"End:", xco,0,4.5*XIC,YIC, &G.scene->r.pefra,PSFRA,MAXFRAMEF, 0, 0, - "The end frame of the animation preview"); + "The end frame of the animation preview (inclusive)"); } else { uiDefButI(block, NUM, REDRAWALL,"Start:", xco,0, 4.5*XIC, YIC, &G.scene->r.sfra,MINFRAMEF, MAXFRAMEF, 0, 0, - "The start frame of the animation"); + "The start frame of the animation (inclusive)"); xco += 4.5*XIC; uiDefButI(block, NUM, REDRAWALL,"End:", xco,0,4.5*XIC,YIC, &G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0, - "The end frame of the animation"); + "The end frame of the animation (inclusive)"); } uiBlockEndAlign(block); @@ -498,7 +498,7 @@ void time_buttons(ScrArea *sa) uiDefButI(block, NUM, B_NEWFRAME, "", xco,0,3.5*XIC,YIC, &(G.scene->r.cfra), MINFRAMEF, MAXFRAMEF, 0, 0, - "Displays Current Frame of animation. Click to change."); + "Displays Current Frame of animation"); xco += 3.5*XIC+16; From b3e5f6b4510bda7a32ab1ea346519c498790af70 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Jan 2008 00:56:22 +0000 Subject: [PATCH 93/99] more tooltip changes --- source/blender/src/buttons_scene.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 4c8aeb2443c..9bd2f9588a9 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1825,7 +1825,7 @@ static void render_panel_output(void) uiBlockSetCol(block, TH_BUT_SETTING1); uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 10, 94, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image"); - uiDefButS(block, NUM, B_NOP, "Threads:", 10, 68, 100, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render"); + uiDefButS(block, NUM, B_NOP, "Threads:", 10, 68, 100, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render (takes advantage of multi-core and multi-processor computers)"); uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); @@ -1839,7 +1839,7 @@ static void render_panel_output(void) uiDefButS(block, MENU, B_REDR, "Render Display %t|Render Window %x1|Image Editor %x0|Full Screen %x2", 72, 10, 120, 19, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output display"); - uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); + uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds filetype extensions to the filename when rendering animations"); /* Dither control */ uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); @@ -1987,7 +1987,7 @@ static void render_panel_anim(void) if(uiNewPanel(curarea, block, "Anim", "Render", 640, 0, 318, 204)==0) return; - uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Render the animation to disk (from first to last frame)"); + uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Render the animation to disk (start to end frame)"); uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockBeginAlign(block); From d5e491c3ef0d2c7d9d7dc68ad680c2e9e53463a0 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Tue, 1 Jan 2008 01:00:05 +0000 Subject: [PATCH 94/99] Recoded particles initial rotations to allow much more flexible settings. --- source/blender/blenkernel/intern/particle.c | 1 - .../blenkernel/intern/particle_system.c | 62 ++++++++++++------- source/blender/makesdna/DNA_particle_types.h | 11 +++- source/blender/src/buttons_object.c | 10 +-- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index d0bf8b412ef..82b2d785c8c 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2795,7 +2795,6 @@ static void default_particle_settings(ParticleSettings *part) part->disp=100; part->from= PART_FROM_FACE; part->length= 1.0; - part->rotfac= 1.0; part->nbetween= 4; part->boidneighbours= 5; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 880fb0c1ef6..ac06f75737f 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1533,10 +1533,9 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi ParticleTexture ptex; ParticleKey state; IpoCurve *icu=0; - float fac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],*q2=0; + float fac, rotfac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],*q2=0; float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0}; - float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}; - + float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0}; float q_one[4]={1.0,0.0,0.0,0.0}, q_phase[4]; part=psys->part; @@ -1637,7 +1636,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi } /* -rotation */ - if(part->rotmode==PART_ROT_RAND){ + if(part->randrotfac != 0.0f){ QUATCOPY(r_rot,pa->r_rot); Mat4ToQuat(ob->obmat,rot); QuatMul(r_rot,r_rot,rot); @@ -1688,34 +1687,49 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0.0; if(part->rotmode){ + /* create vector into which rotation is aligned */ switch(part->rotmode){ case PART_ROT_NOR: - VecMulf(nor,-1.0); - q2= vectoquat(nor, OB_POSX, OB_POSZ); - VecMulf(nor,-1.0); + VecCopyf(rot_vec, nor); break; case PART_ROT_VEL: - VecMulf(vel,-1.0); - q2= vectoquat(vel, OB_POSX, OB_POSZ); - VecMulf(vel,-1.0); + VecCopyf(rot_vec, vel); break; - case PART_ROT_RAND: - q2= r_rot; + case PART_ROT_GLOB_X: + case PART_ROT_GLOB_Y: + case PART_ROT_GLOB_Z: + rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f; + break; + case PART_ROT_OB_X: + case PART_ROT_OB_Y: + case PART_ROT_OB_Z: + VecCopyf(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]); break; } - /* how much to rotate from rest position */ - QuatInterpol(rot,q_one,q2,part->rotfac); + + /* create rotation quat */ + VecMulf(rot_vec,-1.0); + q2= vectoquat(rot_vec, OB_POSX, OB_POSZ); - /* phase */ - VecRotToQuat(x_vec,part->phasefac*(float)M_PI,q_phase); + /* randomize rotation quat */ + if(part->randrotfac!=0.0f) + QuatInterpol(rot, q2, r_rot, part->randrotfac); + else + QuatCopy(rot,q2); - /* combine amount & phase */ - QuatMul(pa->state.rot,rot,q_phase); + /* rotation phase */ + phasefac = part->phasefac; + if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */ + phasefac += part->randphasefac * pa->r_ave[0]; + VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase); + + /* combine base rotation & phase */ + QuatMul(pa->state.rot, rot, q_phase); } /* -angular velocity */ - pa->state.ave[0]=pa->state.ave[1]=pa->state.ave[2]=0.0; + pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0; if(part->avemode){ switch(part->avemode){ @@ -1736,15 +1750,15 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi } } - pa->dietime=pa->time+pa->lifetime; + pa->dietime = pa->time + pa->lifetime; if(pa->time >= cfra) - pa->alive=PARS_UNBORN; + pa->alive = PARS_UNBORN; - pa->state.time=cfra; + pa->state.time = cfra; - pa->stick_ob=0; - pa->flag&=~PARS_STICKY; + pa->stick_ob = 0; + pa->flag &= ~PARS_STICKY; } static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from) { diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 942c837df97..f83c2a59799 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -133,13 +133,13 @@ typedef struct ParticleSettings { /* initial velocity factors */ float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac; - float rotfac, avefac, phasefac; + float avefac, phasefac, randrotfac, randphasefac; /* physical properties */ float mass, size, randsize, reactshape; /* global physical properties */ float acc[3], dragfac, brownfac, dampfac; /* length */ - float length, abslength, randlength, pad; + float length, abslength, randlength; /* children */ int child_nbr, ren_child_nbr; float parents, childsize, childrandsize; @@ -355,7 +355,12 @@ typedef struct ParticleSystem{ /* part->rotmode */ #define PART_ROT_NOR 1 #define PART_ROT_VEL 2 -#define PART_ROT_RAND 3 +#define PART_ROT_GLOB_X 3 +#define PART_ROT_GLOB_Y 4 +#define PART_ROT_GLOB_Z 5 +#define PART_ROT_OB_X 6 +#define PART_ROT_OB_Y 7 +#define PART_ROT_OB_Z 8 /* part->avemode */ #define PART_AVE_SPIN 1 diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 8451a4c8afd..243681bc800 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4139,15 +4139,17 @@ static void object_panel_particle_physics(Object *ob) uiDefBut(block, LABEL, 0, "Rotation:", butx, (buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButBitI(block, TOG, PART_ROT_DYN, B_PART_RECALC, "Dynamic", butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->flag, 0, 0, 0, 0, "Sets rotation to dynamic/constant"); - uiDefButS(block, MENU, B_PART_RECALC, "Rotation %t|Random %x3|Velocity %x2|Normal %x1|None %x0", butx+butw/2,buty,butw/2,buth*4/5, &part->rotmode, 14.0, 0.0, 0, 0, "Select particle rotation mode"); + uiDefButS(block, MENU, B_PART_RECALC, "Rotation%t|Object Z%x8|Object Y%x7|Object X%x6|Global Z%x5|Global Y%x4|Global X%x3|Velocity%x2|Normal%x1|None%x0", butx+butw/2,buty,butw/2,buth*4/5, &part->rotmode, 14.0, 0.0, 0, 0, "Particles initial rotation"); uiBlockSetCol(block, TH_BUT_SETTING2); - uiDefButF(block, NUM, B_PART_RECALC, "Amount:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->rotfac, -1.0, 1.0, 1, 3, "Rotation amount"); - uiDefButF(block, NUM, B_PART_RECALC, "Phase:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->phasefac, -1.0, 1.0, 1, 3, "Initial rotation phase"); + uiDefButF(block, NUM, B_PART_RECALC, "Random:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->randrotfac, 0.0, 1.0, 1, 3, "Randomize rotation"); + uiDefButF(block, NUM, B_PART_RECALC, "Phase:", butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->phasefac, -1.0, 1.0, 1, 3, "Initial rotation phase"); + uiDefButF(block, NUM, B_PART_RECALC, "Rand:", butx+butw/2,buty,butw/2,buth*4/5, &part->randphasefac, 0.0, 1.0, 1, 3, "Randomize rotation phase"); uiBlockSetCol(block, TH_AUTO); uiDefButS(block, MENU, B_PART_RECALC, "Angular v %t|Velocity%x3|Random%x2|Spin%x1|None%x0", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avemode, 14.0, 0.0, 0, 0, "Select particle angular velocity mode"); uiBlockSetCol(block, TH_BUT_SETTING2); - uiDefButF(block, NUM, B_PART_RECALC, "Angular v:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avefac, -200.0, 200.0, 1, 3, "Angular velocity amount"); + if(ELEM(part->avemode,PART_AVE_RAND,PART_AVE_SPIN)) + uiDefButF(block, NUM, B_PART_RECALC, "Angular v:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avefac, -200.0, 200.0, 1, 3, "Angular velocity amount"); uiBlockSetCol(block, TH_AUTO); uiBlockEndAlign(block); From 0a62df356d85eb61cbacf826cc9fb00e4593051b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Jan 2008 02:20:13 +0000 Subject: [PATCH 95/99] find external files wasnt finding the biggest screen area for the file selector, other minor changes. renamed "Dump Screen" to "Screenshot" in the file menu. --- source/blender/src/drawview.c | 21 ++++++++++----------- source/blender/src/header_info.c | 11 ++++++++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 8580774e9dc..69d2a12ad7c 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -1582,7 +1582,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) if(ob->type==OB_MESH) { eve= em->verts.first; while(eve) { - if(eve->f & 1) { + if(eve->f & SELECT) { evedef= eve; tot++; VecAddf(median, median, eve->co); @@ -1705,16 +1705,15 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) Mat4MulVecfl(ob->obmat, median); if(block) { // buttons + int but_y; + if((ob->parent) && (ob->partype == PARBONE)) but_y = 135; + else but_y = 150; + uiBlockBeginAlign(block); - if((ob->parent) && (ob->partype == PARBONE)) { - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, 135, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, 135, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values"); - } - else { - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values"); - } - + uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, but_y, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values"); + uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, but_y, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values"); + uiBlockEndAlign(block); + memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); @@ -1779,7 +1778,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) eve= em->verts.first; while(eve) { - if(eve->f & 1) { + if(eve->f & SELECT) { VecAddf(eve->co, eve->co, median); } eve= eve->next; diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 9f1a31a940a..62450d686a1 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -998,6 +998,11 @@ static void do_info_externalfiles(void *arg, int event) } break; case 13: /* search for referenced files that are not available */ + if(curarea->spacetype==SPACE_INFO) { + ScrArea *sa; + sa= closest_bigger_area(); + areawinset(sa->win); + } activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles); break; } @@ -1061,9 +1066,9 @@ static uiBlock *info_filemenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Image...|F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Dump Subwindow|Ctrl F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Dump Screen|Ctrl Shift F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Rendered Image...|F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, ""); #if GAMEBLENDER == 1 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, ""); #ifdef _WIN32 From 3ef896a9453acb8c564b8a8fd97885958c733436 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 1 Jan 2008 11:44:42 +0000 Subject: [PATCH 96/99] == Sequencer == Attention! Rather large sequencer rewrite: * Implemented layer blending using implicit effects. (works like layers in "The Gimp" or Photoshop.) * Fixed Space-Bar start-stop in preview windows. You can start playback using spacebar within a preview-window and it _works_! * Fixed Flip Y (didn't work for float) * Fixed premul (didn't work for float) * Added IPOs to _all_ tracks. In blend-mode REPLACE it drives the "mul"-parameter in all other blend modes it drives the effect. * you can meta single tracks. * moved "mute track" from "M" to "Shift-M" * added "Shift-L" for "lock track" * changed inner workings for Metas. Now all ImBufs have to use the reference counting mechanism. (Only interesting for coders :) !!! Really important change, that affects current files! Since you can mute tracks and now there is real layer blending capabilities in place, I changed the silly behaviour that chose the output track. Old behaviour: if we have an effect track visible, use the uppermost effect track. If there is _no_ effect track visible, use the lowest input track. New behaviour: always use the uppermost track. With blend modes active: work our way down starting from the uppermost track to the first "replace"-mode track. This is the way the gimp, photoshop, basically _all_ other applications work... So if this change ruins your day: please try to fix your files using "mute". If this doesn't work out, I can still restore the old behaviour, but I really hope, that this is _not_ necessary! Rational: most people won't get affected by this change, since you can't really do anything usefull with the (old) sequencer without at least one effect track and then you are on the safe side... --- source/blender/blenkernel/intern/image.c | 58 ++- source/blender/imbuf/intern/rotate.c | 59 +-- source/blender/include/BSE_seqeffects.h | 1 + source/blender/include/BSE_sequence.h | 3 + source/blender/makesdna/DNA_sequence_types.h | 8 +- source/blender/src/buttons_scene.c | 183 +++++--- source/blender/src/drawseq.c | 30 -- source/blender/src/drawview.c | 5 +- source/blender/src/editipo.c | 14 +- source/blender/src/editseq.c | 1 + source/blender/src/seqeffects.c | 28 +- source/blender/src/sequence.c | 437 +++++++++++++++---- source/blender/src/space.c | 24 +- source/blender/src/toets.c | 10 +- 14 files changed, 597 insertions(+), 264 deletions(-) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d61829891d6..3b40907244a 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -98,32 +98,50 @@ /* used by sequencer and image premul option - IMA_DO_PREMUL */ void converttopremul(struct ImBuf *ibuf) { - int x, y, val; - char *cp; + int x, y; if(ibuf==0) return; - if(ibuf->depth==24) { /* put alpha at 255 */ - - cp= (char *)(ibuf->rect); - for(y=0; yy; y++) { - for(x=0; xx; x++, cp+=4) { - cp[3]= 255; + if (ibuf->rect) { + int val; + char *cp; + if(ibuf->depth==24) { /* put alpha at 255 */ + cp= (char *)(ibuf->rect); + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + cp[3]= 255; + } + } + } else { + cp= (char *)(ibuf->rect); + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + val= cp[3]; + cp[0]= (cp[0]*val)>>8; + cp[1]= (cp[1]*val)>>8; + cp[2]= (cp[2]*val)>>8; + } } } - return; } - - cp= (char *)(ibuf->rect); - for(y=0; yy; y++) { - for(x=0; xx; x++, cp+=4) { - if(cp[3]==0) { - cp[0]= cp[1]= cp[2]= 0; + if (ibuf->rect_float) { + float val; + float *cp; + if(ibuf->depth==24) { /* put alpha at 1.0 */ + cp= ibuf->rect_float;; + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + cp[3]= 1.0; + } } - else if(cp[3]!=255) { - val= cp[3]; - cp[0]= (cp[0]*val)>>8; - cp[1]= (cp[1]*val)>>8; - cp[2]= (cp[2]*val)>>8; + } else { + cp= ibuf->rect_float; + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + val= cp[3]; + cp[0]= cp[0]*val; + cp[1]= cp[1]*val; + cp[2]= cp[2]*val; + } } } } diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c index 42b30d6284f..8f5fb39d956 100644 --- a/source/blender/imbuf/intern/rotate.c +++ b/source/blender/imbuf/intern/rotate.c @@ -43,48 +43,55 @@ void IMB_flipy(struct ImBuf * ibuf) { - short x, y; - unsigned int *top, *bottom, do_float=0, *line; - float *topf=NULL, *bottomf=NULL, *linef=NULL; + int x, y; if (ibuf == NULL) return; - if (ibuf->rect == NULL) return; - - if (ibuf->rect_float) do_float =1; - x = ibuf->x; - y = ibuf->y; + if (ibuf->rect) { + unsigned int *top, *bottom, *line; - top = ibuf->rect; - bottom = top + ((y-1) * x); - line= MEM_mallocN(x*sizeof(int), "linebuf"); + x = ibuf->x; + y = ibuf->y; + + top = ibuf->rect; + bottom = top + ((y-1) * x); + line= MEM_mallocN(x*sizeof(int), "linebuf"); - if (do_float) { + y >>= 1; + + for(;y>0;y--) { + memcpy(line, top, x*sizeof(int)); + memcpy(top, bottom, x*sizeof(int)); + memcpy(bottom, line, x*sizeof(int)); + bottom -= x; + top+= x; + } + + MEM_freeN(line); + } + + if (ibuf->rect_float) { + float *topf=NULL, *bottomf=NULL, *linef=NULL; + + x = ibuf->x; + y = ibuf->y; + topf= ibuf->rect_float; bottomf = topf + 4*((y-1) * x); linef= MEM_mallocN(4*x*sizeof(float), "linebuff"); - } - y >>= 1; - for(;y>0;y--) { - - memcpy(line, top, x*sizeof(int)); - memcpy(top, bottom, x*sizeof(int)); - memcpy(bottom, line, x*sizeof(int)); - bottom -= x; - top+= x; - - if(do_float) { + y >>= 1; + + for(;y>0;y--) { memcpy(linef, topf, 4*x*sizeof(float)); memcpy(topf, bottomf, 4*x*sizeof(float)); memcpy(bottomf, linef, 4*x*sizeof(float)); bottomf -= 4*x; topf+= 4*x; } + + MEM_freeN(linef); } - - MEM_freeN(line); - if(linef) MEM_freeN(linef); } void IMB_flipx(struct ImBuf * ibuf) diff --git a/source/blender/include/BSE_seqeffects.h b/source/blender/include/BSE_seqeffects.h index 2962bbf3676..2dde9d3cc79 100644 --- a/source/blender/include/BSE_seqeffects.h +++ b/source/blender/include/BSE_seqeffects.h @@ -89,6 +89,7 @@ struct SeqEffectHandle { }; struct SeqEffectHandle get_sequence_effect(struct Sequence * seq); +struct SeqEffectHandle get_sequence_blend(struct Sequence * seq); int get_sequence_effect_num_inputs(int seq_type); void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force); diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 46e0aa6ff1f..3f86c6b163b 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -64,6 +64,9 @@ void reload_sequence_new_file(struct Sequence * seq); void sort_seq(void); void clear_scene_in_allseqs(struct Scene *sce); +char *give_seqname_by_type(int type); +char *give_seqname(struct Sequence *seq); + int evaluate_seq_frame(int cfra); struct StripElem *give_stripelem(struct Sequence *seq, int cfra); struct TStripElem *give_tstripelem(struct Sequence *seq, int cfra); diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index b401ee05433..066e23ca984 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -50,6 +50,7 @@ typedef struct StripElem { typedef struct TStripElem { struct ImBuf *ibuf; + struct ImBuf *ibuf_comp; struct TStripElem *se1, *se2, *se3; short ok; short pad; @@ -267,14 +268,17 @@ typedef struct SpeedControlVars { #define SEQ_TRANSFORM 27 #define SEQ_COLOR 28 #define SEQ_SPEED 29 +#define SEQ_EFFECT_MAX 29 #define STRIPELEM_FAILED 0 #define STRIPELEM_OK 1 #define STRIPELEM_META 2 #define SEQ_BLEND_REPLACE 0 -#define SEQ_BLEND_ALPHA_OVER 1 - +/* all other BLEND_MODEs are simple SEQ_EFFECT ids and therefore identical + to the table above. (Only those effects that handle _exactly_ two inputs, + otherwise, you can't really blend, right :) !) +*/ #endif diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 9bd2f9588a9..dda48a298ff 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -483,22 +483,40 @@ static void sound_panel_sound(bSound *sound) static char* seq_panel_blend_modes() { static char string[2048]; - char formatstring[2048]; - strcpy(formatstring, "Blend mode: %%t|%s %%x%d|%s %%x%d"); - sprintf(string, formatstring, - "REPLACE", SEQ_BLEND_REPLACE, - "TODO: ALPHA OVER", SEQ_BLEND_ALPHA_OVER); - return string; + Sequence *last_seq = get_last_seq(); + sprintf(string, "Blend mode: %%t|%s %%x%d", + "Replace", SEQ_BLEND_REPLACE); + + /* + Blending can only work without effect strips. + Otherwise, one would have + to decide, what the effect strips IPO should do: + - drive the effect _or_ + - drive the blend mode ? + + Also: effectdata is used by these implicit effects, + so that would collide also. + */ + + if (!(last_seq->type & SEQ_EFFECT)) { + int i; + + for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) { + if (get_sequence_effect_num_inputs(i) == 2) { + sprintf(string + strlen(string), + "|%s %%x%d", + give_seqname_by_type(i), i); + } + } + } + return string; } static void seq_panel_editing() { Sequence *last_seq = get_last_seq(); - char * seq_names[] = { "Image", "Meta", "Scene", "Movie", - "Snd RAM", "Snd HD", - "", "Effect" }; uiBlock *block; static char strdata[1024]; char * str = strdata; @@ -512,8 +530,7 @@ static void seq_panel_editing() 10, 230, 318, 204) == 0) return; uiDefBut(block, LABEL, - 0, (last_seq->type >= SEQ_EFFECT) ? - "Effect" : seq_names[last_seq->type], + 0, give_seqname(last_seq), 10,140,60,19, 0, 0, 0, 0, 0, ""); @@ -575,11 +592,13 @@ static void seq_panel_editing() uiDefButI(block, NUM, B_SEQ_BUT_TRANSFORM, "Start-Ofs", 10, 60, 120, 20, &last_seq->startofs, - 0.0, last_seq->len, 0.0, 0.0, "Start offset"); + 0.0, last_seq->len - last_seq->endofs, + 0.0, 0.0, "Start offset"); uiDefButI(block, NUM, B_SEQ_BUT_TRANSFORM, "End-Ofs", 130, 60, 120, 19, &last_seq->endofs, - 0.0, last_seq->len, 0.0, 0.0, "End offset"); + 0.0, last_seq->len - last_seq->startofs, + 0.0, 0.0, "End offset"); } } @@ -672,16 +691,20 @@ static void seq_panel_input() { Sequence *last_seq = get_last_seq(); uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_input", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Input", "Sequencer", 10, 230, 318, 204) == 0) return; - uiDefBut(block, TEX, - B_SEQ_BUT_RELOAD_FILE, "Dir: ", - 10,140,240,19, last_seq->strip->dir, - 0.0, 160.0, 100, 0, ""); + if (last_seq->type == SEQ_MOVIE + || last_seq->type == SEQ_IMAGE) { + uiDefBut(block, TEX, + B_SEQ_BUT_RELOAD_FILE, "Dir: ", + 10,140,240,19, last_seq->strip->dir, + 0.0, 160.0, 100, 0, ""); + } if (last_seq->type == SEQ_IMAGE) { StripElem * se = give_stripelem(last_seq, CFRA); @@ -702,73 +725,89 @@ static void seq_panel_input() 0.0, 80.0, 100, 0, ""); } - uiDefButBitI(block, TOG, SEQ_USE_CROP, - B_SEQ_BUT_RELOAD, "Use Crop", - 10,100,240,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Crop image before processing."); + if (last_seq->type == SEQ_MOVIE + || last_seq->type == SEQ_IMAGE + || last_seq->type == SEQ_SCENE) { + uiDefButBitI(block, TOG, SEQ_USE_CROP, + B_SEQ_BUT_RELOAD, "Use Crop", + 10,100,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Crop image before processing."); - if (last_seq->flag & SEQ_USE_CROP) { - if (!last_seq->strip->crop) { - last_seq->strip->crop = - MEM_callocN(sizeof(struct StripCrop), - "StripCrop"); + if (last_seq->flag & SEQ_USE_CROP) { + if (!last_seq->strip->crop) { + last_seq->strip->crop = + MEM_callocN(sizeof(struct StripCrop), + "StripCrop"); + } + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Top", + 10, 80, 120, 20, + &last_seq->strip->crop->top, + 0.0, 4096, 0.0, 0.0, "Top of source image"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Bottom", + 130, 80, 120, 20, + &last_seq->strip->crop->bottom, + 0.0, 4096, 0.0, 0.0, + "Bottom of source image"); + + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Left", + 10, 60, 120, 20, + &last_seq->strip->crop->left, + 0.0, 4096, 0.0, 0.0, "Left"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Right", + 130, 60, 120, 19, + &last_seq->strip->crop->right, + 0.0, 4096, 0.0, 0.0, "Right"); + } + + uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, + B_SEQ_BUT_RELOAD, "Use Translate", + 10,40,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Translate image before processing."); + + if (last_seq->flag & SEQ_USE_TRANSFORM) { + if (!last_seq->strip->transform) { + last_seq->strip->transform = + MEM_callocN( + sizeof(struct StripTransform), + "StripTransform"); + } + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "X-Ofs", + 10, 20, 120, 20, + &last_seq->strip->transform->xofs, + 0.0, 4096, 0.0, 0.0, "X Offset"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Y-Ofs", + 130, 20, 120, 20, + &last_seq->strip->transform->yofs, + 0.0, 4096, 0.0, 0.0, "Y Offset"); } - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Top", - 10, 80, 120, 20, &last_seq->strip->crop->top, - 0.0, 4096, 0.0, 0.0, "Top of source image"); - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Bottom", - 130, 80, 120, 20, &last_seq->strip->crop->bottom, - 0.0, 4096, 0.0, 0.0, "Bottom of source image"); - - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Left", - 10, 60, 120, 20, &last_seq->strip->crop->left, - 0.0, 4096, 0.0, 0.0, "Left"); - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Right", - 130, 60, 120, 19, &last_seq->strip->crop->right, - 0.0, 4096, 0.0, 0.0, "Right"); } - uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, - B_SEQ_BUT_RELOAD, "Use Translate", - 10,40,240,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Translate image before processing."); - - if (last_seq->flag & SEQ_USE_TRANSFORM) { - if (!last_seq->strip->transform) { - last_seq->strip->transform = - MEM_callocN(sizeof(struct StripTransform), - "StripTransform"); - } - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "X-Ofs", - 10, 20, 120, 20, &last_seq->strip->transform->xofs, - 0.0, 4096, 0.0, 0.0, "X Offset"); - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Y-Ofs", - 130, 20, 120, 20, &last_seq->strip->transform->yofs, - 0.0, 4096, 0.0, 0.0, "Y Offset"); - } - - uiDefButI(block, NUM, B_SEQ_BUT_RELOAD_FILE, "A-Start", 10, 0, 120, 20, &last_seq->anim_startofs, - 0.0, MAXFRAMEF, 0.0, 0.0, "Animation start offset in file"); + 0.0, last_seq->len + last_seq->anim_startofs, 0.0, 0.0, + "Animation start offset in file"); uiDefButI(block, NUM, B_SEQ_BUT_RELOAD_FILE, "A-End", 130, 0, 120, 20, &last_seq->anim_endofs, - 0.0, MAXFRAMEF, 0.0, 0.0, "Animation end offset in file"); + 0.0, last_seq->len + last_seq->anim_endofs, 0.0, 0.0, + "Animation end offset in file"); - uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "MPEG-Preseek:", - 10, -20, 240,19, &last_seq->anim_preseek, - 0.0, 50.0, 100,0,"On MPEG-seeking preseek this many frames"); + if (last_seq->type == SEQ_MOVIE) { + uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "MPEG-Preseek:", + 10, -20, 240,19, &last_seq->anim_preseek, + 0.0, 50.0, 100,0, + "On MPEG-seeking preseek this many frames"); + } } diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 02f420dc641..2b301ab90c1 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -99,36 +99,6 @@ static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2) static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2); static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq, int outline_tint, float pixelx); -static char *give_seqname(Sequence *seq) -{ - if(seq->type==SEQ_META) return "Meta"; - else if(seq->type==SEQ_IMAGE) return "Image"; - else if(seq->type==SEQ_SCENE) return "Scene"; - else if(seq->type==SEQ_MOVIE) return "Movie"; - else if(seq->type==SEQ_RAM_SOUND) return "Audio (RAM)"; - else if(seq->type==SEQ_HD_SOUND) return "Audio (HD)"; - else if(seq->typestrip->dir; - else if(seq->type==SEQ_CROSS) return "Cross"; - else if(seq->type==SEQ_GAMCROSS) return "Gamma Cross"; - else if(seq->type==SEQ_ADD) return "Add"; - else if(seq->type==SEQ_SUB) return "Sub"; - else if(seq->type==SEQ_MUL) return "Mul"; - else if(seq->type==SEQ_ALPHAOVER) return "Alpha Over"; - else if(seq->type==SEQ_ALPHAUNDER) return "Alpha Under"; - else if(seq->type==SEQ_OVERDROP) return "Over Drop"; - else if(seq->type==SEQ_WIPE) return "Wipe"; - else if(seq->type==SEQ_GLOW) return "Glow"; - else if(seq->type==SEQ_TRANSFORM) return "Transform"; - else if(seq->type==SEQ_COLOR) return "Color"; - else if(seq->type==SEQ_SPEED) return "Speed"; - else if(seq->type==SEQ_PLUGIN) { - if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) && - seq->plugin && seq->plugin->doit) return seq->plugin->pname; - return "Plugin"; - } - else return "Effect"; - -} static void draw_cfra_seq(void) { glColor3ub(0x30, 0x90, 0x50); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 69d2a12ad7c..8fb5ba6cf2a 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3560,14 +3560,13 @@ int play_anim(int mode) /* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */ curarea->win_swap= WIN_BACK_OK; screen_swapbuffers(); - + while(TRUE) { if (U.uiflag & USER_SHOW_FPS) lredrawtime = PIL_check_seconds_timer(); while(qtest()) { - /* we test events first because of MKEY event */ event= extern_qread(&val); @@ -3588,7 +3587,7 @@ int play_anim(int mode) if(val) add_marker(CFRA-1); } } - if(ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break; + if(val && ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break; inner_play_anim_loop(0, 0); diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 82c897236a2..8d75090d911 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -1099,7 +1099,7 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname else if(blocktype==ID_SEQ) { Sequence *last_seq = get_last_seq(); - if(last_seq && ((last_seq->type & SEQ_EFFECT)||(last_seq->type == SEQ_HD_SOUND)||(last_seq->type == SEQ_RAM_SOUND))) { + if(last_seq) { *from= (ID *)last_seq; *ipo= last_seq->ipo; } @@ -1908,15 +1908,11 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char { Sequence *seq= (Sequence *)from; /* note, sequence is mimicing Id */ - if((seq->type & SEQ_EFFECT)|| - (seq->type == SEQ_RAM_SOUND)|| - (seq->type == SEQ_HD_SOUND)) { - if(seq->ipo==NULL) { - seq->ipo= add_ipo("SeqIpo", ID_SEQ); - } - update_seq_ipo_rect(seq); - return seq->ipo; + if(seq->ipo==NULL) { + seq->ipo= add_ipo("SeqIpo", ID_SEQ); } + update_seq_ipo_rect(seq); + return seq->ipo; } break; case ID_CU: diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index 887737e0dad..dd31ebaad5d 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -946,6 +946,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine) seq->start= cfra; seq->machine= machine; seq->mul= 1.0; + seq->blend_opacity = 100.0; return seq; } diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c index 5ed7ea29e2f..0099e5b9860 100644 --- a/source/blender/src/seqeffects.c +++ b/source/blender/src/seqeffects.c @@ -3014,7 +3014,27 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) struct SeqEffectHandle get_sequence_effect(Sequence * seq) { - struct SeqEffectHandle rval = get_sequence_effect_impl(seq->type); + struct SeqEffectHandle rval; + + if (seq->type & SEQ_EFFECT) { + rval = get_sequence_effect_impl(seq->type); + } + + if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { + rval.load(seq); + seq->flag &= ~SEQ_EFFECT_NOT_LOADED; + } + + return rval; +} + +struct SeqEffectHandle get_sequence_blend(Sequence * seq) +{ + struct SeqEffectHandle rval; + + if (seq->blend_mode != 0) { + rval = get_sequence_effect_impl(seq->blend_mode); + } if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { rval.load(seq); @@ -3028,5 +3048,9 @@ int get_sequence_effect_num_inputs(int seq_type) { struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); - return rval.num_inputs(); + int cnt = rval.num_inputs(); + if (rval.execute) { + return cnt; + } + return 0; } diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 3d7ac3021a1..ba5052350ac 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -87,10 +87,14 @@ void free_tstripdata(int len, TStripElem *se) } for(a=0; aibuf && se->ok != STRIPELEM_META) { + if(se->ibuf) { IMB_freeImBuf(se->ibuf); se->ibuf = 0; } + if(se->ibuf_comp) { + IMB_freeImBuf(se->ibuf_comp); + se->ibuf_comp = 0; + } } MEM_freeN(seo); @@ -380,7 +384,7 @@ void reload_sequence_new_file(Sequence * seq) char str[FILE_MAXDIR+FILE_MAXFILE]; if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE || - seq->type == SEQ_HD_SOUND)) { + seq->type == SEQ_HD_SOUND || seq->type == SEQ_SCENE)) { return; } @@ -421,6 +425,14 @@ void reload_sequence_new_file(Sequence * seq) seq->strip->len = seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS); + } else if (seq->type == SEQ_SCENE) { + seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1; + seq->len -= seq->anim_startofs; + seq->len -= seq->anim_endofs; + if (seq->len < 0) { + seq->len = 0; + } + seq->strip->len = seq->len; } @@ -497,6 +509,54 @@ void clear_scene_in_allseqs(Scene *sce) } } +char *give_seqname_by_type(int type) +{ + switch(type) { + case SEQ_META: return "Meta"; + case SEQ_IMAGE: return "Image"; + case SEQ_SCENE: return "Scene"; + case SEQ_MOVIE: return "Movie"; + case SEQ_RAM_SOUND: return "Audio (RAM)"; + case SEQ_HD_SOUND: return "Audio (HD)"; + case SEQ_CROSS: return "Cross"; + case SEQ_GAMCROSS: return "Gamma Cross"; + case SEQ_ADD: return "Add"; + case SEQ_SUB: return "Sub"; + case SEQ_MUL: return "Mul"; + case SEQ_ALPHAOVER: return "Alpha Over"; + case SEQ_ALPHAUNDER: return "Alpha Under"; + case SEQ_OVERDROP: return "Over Drop"; + case SEQ_WIPE: return "Wipe"; + case SEQ_GLOW: return "Glow"; + case SEQ_TRANSFORM: return "Transform"; + case SEQ_COLOR: return "Color"; + case SEQ_SPEED: return "Speed"; + default: + return 0; + } +} + +char *give_seqname(Sequence *seq) +{ + char * name = give_seqname_by_type(seq->type); + + if (!name) { + if(seq->typestrip->dir; + } else if(seq->type==SEQ_PLUGIN) { + if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) && + seq->plugin && seq->plugin->doit) { + return seq->plugin->pname; + } else { + return "Plugin"; + } + } else { + return "Effect"; + } + } + return name; +} + /* ***************** DO THE SEQUENCE ***************** */ static void make_black_ibuf(ImBuf *ibuf) @@ -561,7 +621,7 @@ static void multibuf(ImBuf *ibuf, float fmul) } } -static void do_effect(int cfra, Sequence *seq, TStripElem *se) +static void do_effect(int cfra, Sequence *seq, TStripElem * se) { TStripElem *se1, *se2, *se3; float fac, facf; @@ -587,7 +647,8 @@ static void do_effect(int cfra, Sequence *seq, TStripElem *se) early_out = sh.early_out(seq, fac, facf); if (early_out == -1) { /* no input needed */ - sh.execute(seq, cfra, fac, facf, se->ibuf->x, se->ibuf->y, + sh.execute(seq, cfra, fac, facf, + se->ibuf->x, se->ibuf->y, 0, 0, 0, se->ibuf); return; } @@ -751,7 +812,7 @@ static int evaluate_seq_frame_gen( Sequence *seq; int totseq=0; - memset(seq_arr, 0, sizeof(Sequence*) * MAXSEQ); + memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1)); seq= seqbase->first; while(seq) { @@ -777,59 +838,66 @@ int evaluate_seq_frame(int cfra) } -Sequence *get_shown_sequence(ListBase * seqbasep, int cfra, int chanshown) +static int video_seq_is_rendered(Sequence * seq) +{ + return (seq + && !(seq->flag & SEQ_MUTE) + && seq->type != SEQ_RAM_SOUND + && seq->type != SEQ_HD_SOUND); +} + +static int get_shown_sequences( + ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out) { - Sequence *seq, *seqim, *seqeff; Sequence *seq_arr[MAXSEQ+1]; - int b; + int b = chanshown; + int cnt = 0; - seq = 0; - - if (chanshown > MAXSEQ) { + if (b > MAXSEQ) { return 0; } if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) { - if (chanshown > 0) { - return seq_arr[chanshown]; - } - - /* we take the upper effect strip or - the lowest imagestrip/metastrip */ - seqim= seqeff= 0; - - for(b=1; bflag & SEQ_MUTE) { - /* skip */ - } else if(seq->type & SEQ_EFFECT) { - if(seqeff==0) seqeff= seq; - else if(seqeff->machine < seq->machine) - seqeff= seq; - } else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) { - if(seqim==0) seqim= seq; - else if(seqim->machine > seq->machine) - seqim= seq; + if (b > 0) { + if (seq_arr[b] == 0) { + return 0; + } + } else { + for (b = MAXSEQ; b > 0; b--) { + if (video_seq_is_rendered(seq_arr[b])) { + break; } } } - if(seqeff) seq= seqeff; - else if(seqim) seq= seqim; - else seq= 0; } - return seq; + chanshown = b; + + for (;b > 0; b--) { + if (video_seq_is_rendered(seq_arr[b])) { + if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) { + break; + } + } + } + + for (;b <= chanshown; b++) { + if (video_seq_is_rendered(seq_arr[b])) { + seq_arr_out[cnt++] = seq_arr[b]; + } + } + + return cnt; } -static Sequence * get_shown_seq_from_metastrip(Sequence * seqm, int cfra) +static int get_shown_seq_from_metastrip(Sequence * seqm, int cfra, + Sequence ** seq_arr_out) { - return get_shown_sequence(&seqm->seqbase, cfra, 0); + return get_shown_sequences(&seqm->seqbase, cfra, 0, seq_arr_out); } void set_meta_stripdata(Sequence *seqm) { - Sequence *seq; TStripElem *se; int a, cfra; @@ -847,10 +915,13 @@ void set_meta_stripdata(Sequence *seqm) /* sets all ->se1 pointers in stripdata, to read the ibuf from it */ for(a=0; alen; a++, se++) { + int cnt; + Sequence *seq_arr[MAXSEQ+1]; + cfra= a+seqm->start; - seq = get_shown_seq_from_metastrip(seqm, cfra); - if (seq) { - se->se1= give_tstripelem(seq, cfra); + cnt = get_shown_seq_from_metastrip(seqm, cfra, seq_arr); + if (cnt) { + se->se1= give_tstripelem(seq_arr[cnt-1], cfra); } else { se->se1= 0; } @@ -875,6 +946,8 @@ void set_meta_stripdata(Sequence *seqm) static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) { + float mul; + seq->strip->orx= se->ibuf->x; seq->strip->ory= se->ibuf->y; @@ -946,8 +1019,16 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) if(seq->mul == 0.0) { seq->mul = 1.0; } - if(seq->mul != 1.0) { - multibuf(se->ibuf, seq->mul); + + mul = seq->mul; + + if(seq->blend_mode == SEQ_BLEND_REPLACE + && seq->ipo && seq->ipo->curve.first) { + do_seq_ipo(seq, cfra); + mul *= seq->facf0; + } + if(mul != 1.0) { + multibuf(se->ibuf, mul); } if(seq->flag & SEQ_MAKE_PREMUL) { @@ -968,40 +1049,66 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) } } -static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra); +/* test if image too small or discarded from cache: reload */ + +static void test_and_auto_discard_ibuf(TStripElem * se) +{ + if (se->ibuf) { + if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty + || !(se->ibuf->rect || se->ibuf->rect_float)) { + IMB_freeImBuf(se->ibuf); + + se->ibuf= 0; + se->ok= STRIPELEM_OK; + } + } + if (se->ibuf_comp) { + if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty + || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) { + IMB_freeImBuf(se->ibuf_comp); + + se->ibuf_comp = 0; + } + } +} + +static TStripElem* do_build_seq_array_recursively( + ListBase *seqbasep, int cfra, int chanshown); static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) { char name[FILE_MAXDIR+FILE_MAXFILE]; - if (seq->type != SEQ_META && se->ibuf) { - /* test if image too small - or discarded from cache: reload */ - if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty - || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - se->ok= STRIPELEM_OK; - } + + if (seq->type != SEQ_META) { + test_and_auto_discard_ibuf(se); } if(seq->type == SEQ_META) { if(seq->seqbase.first) { - Sequence * seqmshown= - get_shown_seq_from_metastrip(seq, cfra); - if (seqmshown) { - if(cfra< seq->start) - do_build_seq_recursively(seqmshown, seq->start); - else if(cfra> seq->start+seq->len-1) - do_build_seq_recursively(seqmshown, seq->start + seq->len-1); - else do_build_seq_recursively(seqmshown, cfra); + if(cfra < seq->start) { + do_build_seq_array_recursively( + &seq->seqbase, + seq->start, 0); + } else if(cfra > seq->start + seq->len - 1) { + do_build_seq_array_recursively( + &seq->seqbase, + seq->start + seq->len - 1, 0); + } else { + do_build_seq_array_recursively( + &seq->seqbase, + cfra, 0); } } se->ok = STRIPELEM_META; if(se->se1 == 0) set_meta_stripdata(seq); if(se->se1) { - se->ibuf= se->se1->ibuf; + if(se->ibuf) { + IMB_freeImBuf(se->ibuf); + } + se->ibuf = se->se1->ibuf_comp; + IMB_refImBuf(se->ibuf); } } else if(seq->type & SEQ_EFFECT) { /* should the effect be recalculated? */ @@ -1086,7 +1193,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) /* hrms, set_scene still needed? work on that... */ if(sce!=oldsce) set_scene_bg(sce); - RE_BlenderFrame(re, sce, seq->sfra + se->nr); + RE_BlenderFrame(re, sce, + seq->sfra+se->nr+seq->anim_startofs); if(sce!=oldsce) set_scene_bg(oldsce); /* UGLY WARNING, it is set to zero in RE_BlenderFrame */ @@ -1127,6 +1235,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) } } +static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra); + static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) { float fac, facf; @@ -1229,13 +1339,7 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) if (cfra_left == cfra_right || (s->flags & SEQ_SPEED_BLEND) == 0) { - if(se->ibuf) { - if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty - || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - } - } + test_and_auto_discard_ibuf(se); if (se->ibuf == NULL) { se1 = do_build_seq_recursively_impl( @@ -1333,6 +1437,171 @@ static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) } } +static TStripElem* do_build_seq_array_recursively( + ListBase *seqbasep, int cfra, int chanshown) +{ + Sequence* seq_arr[MAXSEQ+1]; + int count; + int i; + TStripElem* se = 0; + + count = get_shown_sequences(seqbasep, cfra, chanshown, &seq_arr); + + if (!count) { + return 0; + } + + se = give_tstripelem(seq_arr[count - 1], cfra); + + test_and_auto_discard_ibuf(se); + + if (se->ibuf_comp != 0) { + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); + return se; + } + + + if(count == 1) { + se = do_build_seq_recursively(seq_arr[0], cfra); + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf_comp); + return se; + } + + + for (i = count - 1; i >= 0; i--) { + int early_out; + Sequence * seq = seq_arr[i]; + struct SeqEffectHandle sh; + + se = give_tstripelem(seq, cfra); + + test_and_auto_discard_ibuf(se); + + if (se->ibuf_comp != 0) { + break; + } + if (seq->blend_mode == SEQ_BLEND_REPLACE) { + do_build_seq_recursively(seq, cfra); + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf); + break; + } + + sh = get_sequence_blend(seq_arr[i]); + + seq->facf0 = seq->facf1 = 1.0; + + if(seq->ipo && seq->ipo->curve.first) { + do_seq_ipo(seq, cfra); + } + + if( G.scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1; + + seq->facf0 *= seq->blend_opacity / 100.0; + seq->facf1 *= seq->blend_opacity / 100.0; + + early_out = sh.early_out(seq, seq->facf0, seq->facf1); + + switch (early_out) { + case -1: + case 2: + do_build_seq_recursively(seq, cfra); + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf_comp); + break; + case 1: + if (i == 0) { + se->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); + } + break; + case 0: + do_build_seq_recursively(seq, cfra); + break; + } + + if (se->ibuf_comp) { + break; + } + } + + i++; + + for (; i < count; i++) { + Sequence * seq = seq_arr[i]; + struct SeqEffectHandle sh = get_sequence_blend(seq); + TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra); + TStripElem* se2 = give_tstripelem(seq_arr[i], cfra); + + int early_out = sh.early_out(seq, seq->facf0, seq->facf1); + switch (early_out) { + case 0: { + int x= se2->ibuf->x; + int y= se2->ibuf->y; + + if (se1->ibuf_comp->rect_float || + se2->ibuf->rect_float) { + se2->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rectfloat, 0); + } else { + se2->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + } + + + if (!se1->ibuf_comp->rect_float && + se2->ibuf_comp->rect_float) { + IMB_float_from_rect(se1->ibuf_comp); + } + if (!se2->ibuf->rect_float && + se2->ibuf_comp->rect_float) { + IMB_float_from_rect(se2->ibuf); + } + + if (!se1->ibuf_comp->rect && + !se2->ibuf_comp->rect_float) { + IMB_rect_from_float(se1->ibuf); + } + if (!se2->ibuf->rect && + !se2->ibuf_comp->rect_float) { + IMB_rect_from_float(se2->ibuf); + } + + sh.execute(seq, cfra, seq->facf0, seq->facf1, x, y, + se1->ibuf_comp, se2->ibuf, 0, + se2->ibuf_comp); + + IMB_cache_limiter_insert(se2->ibuf_comp); + IMB_cache_limiter_ref(se2->ibuf_comp); + IMB_cache_limiter_touch(se2->ibuf_comp); + + IMB_cache_limiter_unref(se1->ibuf_comp); + IMB_cache_limiter_unref(se2->ibuf); + + break; + } + case 1: { + se2->ibuf_comp = se1->ibuf; + IMB_refImBuf(se2->ibuf_comp); + + break; + } + } + se = se2; + } + + return se; +} + /* * returned ImBuf is refed! * you have to unref after usage! @@ -1340,7 +1609,6 @@ static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) { - Sequence *seqfirst=0; Editing *ed; int count; ListBase *seqbasep; @@ -1360,19 +1628,13 @@ static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) seqrectx= rectx; /* bad bad global! */ seqrecty= recty; - seqfirst = get_shown_sequence(seqbasep, cfra, chanshown); - - if (!seqfirst) { - return 0; - } - - se = do_build_seq_recursively(seqfirst, cfra); + se = do_build_seq_array_recursively(seqbasep, cfra, chanshown); if(!se) { return 0; } - return se->ibuf; + return se->ibuf_comp; } ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, @@ -1728,13 +1990,16 @@ ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown) static void free_imbuf_strip_elem(TStripElem *se) { - if (se->ibuf) { - if (se->ok != STRIPELEM_META && se->ibuf != 0) - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - se->ok= STRIPELEM_OK; - se->se1= se->se2= se->se3= 0; + if(se->ibuf) { + IMB_freeImBuf(se->ibuf); } + if(se->ibuf_comp) { + IMB_freeImBuf(se->ibuf_comp); + } + se->ibuf_comp = 0; + se->ibuf= 0; + se->ok= STRIPELEM_OK; + se->se1= se->se2= se->se3= 0; } static void free_anim_seq(Sequence *seq) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index bfb67b6a07d..81a5606d7c4 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4667,11 +4667,7 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case SPACEKEY: if (G.qual==0) { - if (sseq->mainb) { - play_anim(1); - } else { - add_sequence(-1); - } + add_sequence(-1); } break; case BKEY: @@ -4729,6 +4725,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) select_linked_seq( 0 ); } else if((G.qual==LR_CTRLKEY)) { /* Cut at current frame */ select_linked_seq( 2 ); + } else if ((G.qual==LR_SHIFTKEY)) { + if (last_seq) { + last_seq->flag ^= SEQ_LOCK; + doredraw = 1; + } } break; case YKEY: @@ -4740,17 +4741,14 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.qual==LR_ALTKEY) { un_meta(); break; /*dont redraw timeline etc */ - } else if((G.qual==0)){ - if ((last_seq) && - (last_seq->type == SEQ_RAM_SOUND - || last_seq->type == SEQ_HD_SOUND)) - { + } else if(G.qual == 0){ + make_meta(); + break; /*dont redraw timeline etc */ + } else if (G.qual==LR_SHIFTKEY) { + if (last_seq) { last_seq->flag ^= SEQ_MUTE; doredraw = 1; - } else { - make_meta(); } - break; /*dont redraw timeline etc */ } else if ((G.qual==(LR_CTRLKEY|LR_ALTKEY) )) { add_marker(CFRA); } else if ((G.qual==LR_CTRLKEY)) { diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 53bbfb3fb69..088d91f7418 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -749,7 +749,15 @@ int blenderqread(unsigned short event, short val) case BACKSPACEKEY: break; - + case SPACEKEY: + if (curarea && curarea->spacetype==SPACE_SEQ) { + SpaceSeq *sseq= curarea->spacedata.first; + if (G.qual==0 && sseq->mainb) { + play_anim(1); + return 0; + } + } + break; case AKEY: if(textediting==0 && textspace==0) { if ((G.qual==LR_ALTKEY) && (curarea && curarea->spacetype==SPACE_VIEW3D)) { From 65f1999435224c14ddbe232535dacd52b1ae465a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 1 Jan 2008 14:13:37 +0000 Subject: [PATCH 97/99] Bugfix #8032 The warning i've coded 1.5 year ago, to warn when a .blend was written by newer executable, failed on the .B.blend load case... UI not property initialized then. This at least fixes the crash, a menu won't pop up correctly though... luckily the warning works for regular load or ctrl-x --- source/blender/blenlib/intern/BLI_ghash.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 5846bbda40e..6af377edfba 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -117,14 +117,16 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val) { } } -void* BLI_ghash_lookup(GHash *gh, void *key) { - unsigned int hash= gh->hashfp(key)%gh->nbuckets; - Entry *e; - - for (e= gh->buckets[hash]; e; e= e->next) - if (gh->cmpfp(key, e->key)==0) - return e->val; - +void* BLI_ghash_lookup(GHash *gh, void *key) +{ + if(gh) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + + for (e= gh->buckets[hash]; e; e= e->next) + if (gh->cmpfp(key, e->key)==0) + return e->val; + } return NULL; } From 9db2035e3650ecbd1baf1943c490d6a4e140f2c3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Jan 2008 16:14:08 +0000 Subject: [PATCH 98/99] while trying to debug memory leaks, extended MEM_printmemlist to print a python dict and some lines at the end to format it in a useful way when run as a python script. --- intern/guardedalloc/intern/mallocn.c | 25 +++++++++++++++++++++++-- source/blender/src/editscreen.c | 9 +++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 51c2a2427b5..44909bbea54 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -333,6 +333,7 @@ void *MEM_mapallocN(unsigned int len, const char *str) } +/* Prints in python syntax for easy */ void MEM_printmemlist() { MemHead *membl; @@ -341,13 +342,33 @@ void MEM_printmemlist() membl = membase->first; if (membl) membl = MEMNEXT(membl); + + print_error("# membase_debug.py\n"); + print_error("membase = [\\\n"); while(membl) { - print_error("%s len: %d %p\n",membl->name,membl->len, membl+1); + fprintf(stderr, "{'len':%i, 'name':'''%s''', 'pointer':'%p'},\\\n", membl->len, membl->name, membl+1); if(membl->next) membl= MEMNEXT(membl->next); else break; } - + fprintf(stderr, "]\n\n"); + fprintf(stderr, +"mb_userinfo = {}\n" +"totmem = 0\n" +"for mb_item in membase:\n" +"\tmb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n" +"\tmb_item_user_size[0] += 1 # Add a user\n" +"\tmb_item_user_size[1] += mb_item['len'] # Increment the size\n" +"\ttotmem += mb_item['len']\n" +"print '(membase) items:', len(membase), '| unique-names:', len(mb_userinfo), '| total-mem:', totmem\n" +"mb_userinfo_sort = mb_userinfo.items()\n" +"for sort_name, sort_func in (('size', lambda a: -a[1][1]), ('users', lambda a: -a[1][0]), ('name', lambda a: a[0])):\n" +"\tprint '\\nSorting by:', sort_name\n" +"\tmb_userinfo_sort.sort(key = sort_func)\n" +"\tfor item in mb_userinfo_sort:\n" +"\t\tprint 'name:%%s, users:%%i, len:%%i' %% (item[0], item[1][0], item[1][1])\n" + ); + mem_unlock_thread(); } diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index 35c0692510d..43d163bff09 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -1397,9 +1397,14 @@ void screenmain(void) towin= 0; } else if (event==QKEY) { - if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT); + /* Temp place to print mem debugging info ctrl+alt+shift + qkey */ + if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) { + MEM_printmemlist(); + } + + else if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT); else { - if(val && (G.qual & LR_CTRLKEY)) { + if(val && (G.qual == LR_CTRLKEY)) { if(okee("Quit Blender")) exit_usiblender(); } towin= 0; From fb3ed9e0a573d9296caddeba0f705b83949ee3ad Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 1 Jan 2008 18:38:41 +0000 Subject: [PATCH 99/99] == Sequencer == Added some additional NULL-checks. (se->ibuf can be null, shame on me :) --- source/blender/src/sequence.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index ba5052350ac..88766089317 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1465,8 +1465,10 @@ static TStripElem* do_build_seq_array_recursively( if(count == 1) { se = do_build_seq_recursively(seq_arr[0], cfra); - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf_comp); + if (se->ibuf) { + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf_comp); + } return se; } @@ -1485,8 +1487,14 @@ static TStripElem* do_build_seq_array_recursively( } if (seq->blend_mode == SEQ_BLEND_REPLACE) { do_build_seq_recursively(seq, cfra); - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf); + if (se->ibuf) { + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf); + } else { + se->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + } break; } @@ -1509,8 +1517,14 @@ static TStripElem* do_build_seq_array_recursively( case -1: case 2: do_build_seq_recursively(seq, cfra); - se->ibuf_comp = se->ibuf; - IMB_refImBuf(se->ibuf_comp); + if (se->ibuf) { + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf_comp); + } else { + se->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + } break; case 1: if (i == 0) { @@ -1524,6 +1538,11 @@ static TStripElem* do_build_seq_array_recursively( break; case 0: do_build_seq_recursively(seq, cfra); + if (!se->ibuf) { + se->ibuf = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + } break; }